Example #1
0
void CBalloonTip::InitIconImage()
{
	HICON hIcon = LoadIcon(CPaintManagerUI::GetResourceDll(),MAKEINTRESOURCE(m_nIcon));
	if (hIcon)
	{
		ICONINFO icInfo = { 0 };
		if (::GetIconInfo(hIcon, &icInfo))
		{
			BITMAP bitmap; 
			GetObject(icInfo.hbmColor, sizeof(BITMAP), &bitmap);

			Bitmap* pBitmap = NULL;
			Bitmap* pWrapBitmap = NULL;
			if (bitmap.bmBitsPixel != 32)
			{   
				pBitmap = Bitmap::FromHICON(hIcon);
			} 
			else
			{
				pWrapBitmap = Bitmap::FromHBITMAP(icInfo.hbmColor, NULL);
				BitmapData bitmapData;
				Rect rcImage(0,0, pWrapBitmap->GetWidth(), pWrapBitmap->GetHeight());
				pWrapBitmap->LockBits(&rcImage, ImageLockModeRead, pWrapBitmap->GetPixelFormat(), &bitmapData); 

				pBitmap = new Bitmap(bitmapData.Width, bitmapData.Height, bitmapData.Stride,  PixelFormat32bppARGB, (BYTE*)bitmapData.Scan0);

				pWrapBitmap->UnlockBits(&bitmapData);
			}

			//lpIconImage = pBitmap->Clone(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), PixelFormat32bppARGB);

			HBITMAP hBit ;

			pBitmap->GetHBITMAP(ARGB(0,0,0,0),&hBit);

			m_pPM->AddImage(_T("BalloonIcon"),hBit,pBitmap->GetWidth(),pBitmap->GetHeight(),TRUE);

			DeleteObject(icInfo.hbmColor); 
			DeleteObject(icInfo.hbmMask); 
		}
		DeleteObject(hIcon);
	}
}
Example #2
0
static bool ras_decode(Bitmap& target, Stream& stream)
{
	// reset stream
	stream.Seek(0,Stream::START);

	// streamsize - headersize
	int size = stream.GetSize() - 32;
	if ( size < 1 )
		return false;

	// read header
	uint32 magic		= ReadBigEndian<uint32>(stream);
	uint32 width		= ReadBigEndian<uint32>(stream);
	uint32 height		= ReadBigEndian<uint32>(stream);
	uint32 bits			= ReadBigEndian<uint32>(stream);
/*	uint32 length = */	  ReadBigEndian<uint32>(stream);
	uint32 type			= ReadBigEndian<uint32>(stream);
	uint32 maptype		= ReadBigEndian<uint32>(stream);
	uint32 maplength	= ReadBigEndian<uint32>(stream);

	// verify header
	if ( magic != 0x59a66a95 )
		return false;

	if ( bits != 1 && bits != 8 && bits != 24 && bits != 32 )
		return false;

	if ( type != 0 && type != 1 && type != 2 && type != 3 )
		return false;

	// create bitmap
	switch ( bits )
	{
		case 1:  target = Bitmap(width,height,PIXELFORMAT_INTENSITY8); break;
		case 8:  target = Bitmap(width,height,PIXELFORMAT_PALETTE8(NULL)); break;
		case 24: target = Bitmap(width,height,PIXELFORMAT_RGB888); break;
		case 32: target = Bitmap(width,height,PIXELFORMAT_ARGB8888); break;
		default: return false;
	}

	// read colormap
	switch ( maptype )
	{
		// "none" - no palette
		case 0:
		{
			stream.Seek(maplength,Stream::CURRENT);
			break;
		}

		// "equal rgb" -mode palette
		case 1:
		{
			if ( bits != 8 || maplength > 768 )
				return false;

			const PixelFormat& pxf = target.GetPixelFormat();
			Color32* palette = pxf.GetPalette();
			int count = static_cast<int>(maplength / 3);

			int i;
			for ( i=0; i<count; ++i ) palette[i].r = ReadBigEndian<uint8>(stream);
			for ( i=0; i<count; ++i ) palette[i].g = ReadBigEndian<uint8>(stream);
			for ( i=0; i<count; ++i ) palette[i].b = ReadBigEndian<uint8>(stream);
			for ( i=0; i<count; ++i ) palette[i].a = 0xff;

			break;
		}

		// "raw" -mode palette
		// TODO: this code has not been tested
		//       (couldn't find files to test with or specification)
		//       this is my best guess how the "raw" mode works!
		case 2:
		{
			if ( bits != 8 || maplength > 768 )
				return false;

			const PixelFormat& pxf = target.GetPixelFormat();
			Color32* palette = pxf.GetPalette();
			int count = static_cast<int>(maplength / 3);

			for ( int i=0; i<count; ++i )
			{
				palette[i].r = ReadBigEndian<uint8>(stream);
				palette[i].g = ReadBigEndian<uint8>(stream);
				palette[i].b = ReadBigEndian<uint8>(stream);
				palette[i].a = 0xff;
			}
		}

		// unknown fileformat
		default: return false;
	}

	// decode buffer
	int buffersize = stream.GetSize() - stream.GetOffset();
	uint8* buffer = new uint8[buffersize];
	stream.Read(buffer,buffersize);

	// read image
	uint8* image = target.GetImage();

	int numpixel = width * height;
	if ( numpixel < 1 )
		return false;

	switch ( bits )
	{
		case 1:
		{
			switch ( type )
			{
				case 0:
				case 1:
				case 3:
				{
					int ycount = static_cast<int>(height);
					while ( ycount-- )
					{
						int bitcount = -1;
						uint8 v = 0;
						int xcount = static_cast<int>(width);
						while ( xcount-- )
						{
							if ( bitcount < 0 )
							{
								bitcount = 7;
								v = *buffer++;
							}
							*image++ = (v >> (bitcount--)) & 1 ? 0 : 255;
						}
					}
					break;
				}
				case 2:
				{
					// TODO: RLE decoder
					// TODO: special handling of 1 bit stream
					break;
				}
			}
			break;
		}

		case 8:
		{
			switch ( type )
			{
				case 0:
				case 1:
				case 3:
				{
					memcpy(image,buffer,numpixel);
					break;
				}
				case 2:
				{
					// TODO: RLE decoder
					// TODO: RGB/BGR fix
					// TODO: test rasrle()
					rasrle(image,buffer,numpixel);
					break;
				}
			}
			break;
		}

		case 24:
		{
			switch ( type )
			{
				case 0:
				case 1:
				{
					memcpy(image,buffer,numpixel*3);
					break;
				}
				case 2:
				{
					// TODO: RLE decoder
					// TODO: RGB/BGR fix
					// TODO: test rasrle()
					rasrle(image,buffer,numpixel*3);
					break;
				}
				case 3:
				{
					while ( numpixel-- )
					{
						image[0] = buffer[2];
						image[1] = buffer[1];
						image[2] = buffer[0];
						buffer += 3;
						image += 3;
					}
					break;
				}
			}
			break;
		}

		case 32:
		{
			switch ( type )
			{
				case 0:
				case 1:
				{
					while ( numpixel-- )
					{
						image[0] = buffer[1];
						image[1] = buffer[2]; 
						image[2] = buffer[3];
						image[3] = buffer[0];
						buffer += 4;
						image += 4;
					}
					break;
				}
				case 2:
				{
					// TODO: RLE decoder
					// TODO: RGB/BGR fix
					// TODO: test rasrle()
					rasrle(image,buffer,numpixel*4);
					break;
				}
				case 3:
				{
					while ( numpixel-- )
					{
						image[0] = buffer[3];
						image[1] = buffer[2];
						image[2] = buffer[1];
						image[3] = buffer[0];
						buffer += 4;
						image += 4;
					}
					break;
				}
			}
			break;
		}
	}

	// free decode buffer
	delete[] buffer;

	return true;
}
Example #3
0
int loadImage(struct textureTableIndexStruct *tti, char *fname)
{
	/* http://msdn.microsoft.com/en-us/library/ms536298(VS.85).aspx   GDI+ Lockbits example - what this function is based on*/
	/* http://www.microsoft.com/downloads/details.aspx?FamilyID=6a63ab9c-df12-4d41-933c-be590feaa05a&DisplayLang=en  GDI+ redistributable download - gdiplus.dll 2MB */
	if(!loaded)
	{
		initImageLoader();
		loaded = 1;
	}
	// convert to wide char http://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx   
	//fname = "C:/source2/freewrl/freex3d/tests/helpers/brick.png";  
    //fname = "junk.jpg"; //test failure condition
	size_t origsize = strlen(fname) + 1;
	char* fname2 = (char*) malloc(origsize);
	strcpy(fname2,fname);
	for(int jj=0;jj<strlen(fname2);jj++)
		if(fname2[jj] == '/' ) fname2[jj] = '\\';

    const size_t newsize = 225;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    //mbstowcs_s(&convertedChars, wcstring, origsize, fname, _TRUNCATE);
#if _MSC_VER >= 1500
    mbstowcs_s(&convertedChars, wcstring, origsize, fname2, _TRUNCATE);
#else
    mbstowcs(wcstring, fname2, MB_CUR_MAX);
#endif

	free(fname2);
	Bitmap *bitmap = NULL;
	Status stat;
	bitmap = Bitmap::FromFile(wcstring,false); //new Bitmap(wcstring); //or Bitmap::FromFile(wcstring,false); L"LockBitsTest1.bmp");
	// verifying the success of constructors http://msdn.microsoft.com/en-us/library/ms533801(VS.85).aspx

	stat = bitmap->GetLastStatus(); // http://msdn.microsoft.com/en-us/library/ms535410(VS.85).aspx
	if(stat != Ok)
		return 0; //should come here if it can't find the image file
   BitmapData* bitmapData = new BitmapData;

//#define verbose 1
#ifdef verbose
   printf("bitmap W=%d H=%d\n",bitmap->GetWidth(),bitmap->GetHeight());
   /* http://msdn.microsoft.com/en-us/library/ms535387(VS.85).aspx GetPixelFormat
	  http://msdn.microsoft.com/en-us/library/ms534412(v=VS.85).aspx  pixelFormat constants
	  http://msdn.microsoft.com/en-us/library/ms534136(v=VS.85).aspx   Image::GetFlags ImageFlagsColorSpaceGRAY      = 0x0040,

   */
   UINT flags = bitmap->GetFlags();
   printf("The value of flags, in hexadecimal form, is %x.\n", flags);

   // Is the ColorSpaceRGB flag set?
   if(flags & ImageFlagsColorSpaceRGB)
      printf("The ColorSpaceRGB flag is set.\n");
   else if(flags & ImageFlagsColorSpaceGRAY)
     printf("The ColorSpaceGRAY flag is set.\n");
   printf("bitmap format index =%d %d\n",bitmap->GetPixelFormat()%256,bitmap->GetPixelFormat());
   if(Gdiplus::IsAlphaPixelFormat(bitmap->GetPixelFormat()) ) 
	   printf("has alpha channel\n");
   else
	   printf("no alpha channel\n");
   if(Gdiplus::IsCanonicalPixelFormat(bitmap->GetPixelFormat()) )
	   printf("is canonical\n");
   else
	   printf("not canonical\n");
   printf("Number of bits per pixel %d\n",Gdiplus::GetPixelFormatSize(bitmap->GetPixelFormat()));
#endif
#undef verbose
   bool flipVertically = true;
   Rect rect(0,0,bitmap->GetWidth(),bitmap->GetHeight());
   if(flipVertically)
		bitmapData->Stride = -bitmap->GetWidth()*4;
   else
	   bitmapData->Stride = bitmap->GetWidth()*4;
   bitmapData->Width = bitmap->GetWidth();
   bitmapData->Height = bitmap->GetHeight();
   bitmapData->PixelFormat = PixelFormat32bppARGB;
   int totalbytes = bitmap->GetWidth() * bitmap->GetHeight() * 4; //tti->depth;
   unsigned char * blob = (unsigned char*)malloc(totalbytes);
   if(flipVertically)
		bitmapData->Scan0 = &blob[bitmap->GetWidth()*bitmap->GetHeight()*4 + bitmapData->Stride]; 
   else
	   bitmapData->Scan0 = blob;

   // Lock a rectangular portion of the bitmap for reading.
   bitmap->LockBits(
      &rect,
      ImageLockModeRead|ImageLockModeUserInputBuf,
	  PixelFormat32bppARGB, //PixelFormat24bppRGB, 
      bitmapData);

#ifdef verbose
   printf("The stride is %d.\n\n", bitmapData->Stride);
   printf("bitmapData W=%d H=%d\n",bitmapData->Width,bitmapData->Height);
#endif
#ifdef verbose

   // Display the hexadecimal value of each pixel in the 5x3 rectangle.
   UINT* pixels = (UINT*)bitmapData->Scan0;

   for(UINT row = 0; row < 23; ++row)
   {
      for(UINT col = 0; col < 5; ++col)
      {
         printf("%x\n", pixels[row * bitmapData->Stride / 4 + col]);
      }
      printf("- - - - - - - - - - \n");
   }
#endif

   //deep copy data so browser owns it (and does its FREE_IF_NZ) and we can delete our copy here and forget about it
   tti->x = bitmapData->Width;
   tti->y = bitmapData->Height;
   tti->frames = 1;
   tti->texdata = blob; 
   if(!blob)
	   printf("ouch in gdiplus image loader L140 - no image data\n");
   //tti->hasAlpha = Gdiplus::IsAlphaPixelFormat(bitmapData->PixelFormat)?1:0; 
   tti->hasAlpha = Gdiplus::IsAlphaPixelFormat(bitmap->GetPixelFormat())?1:0; 
   //printf("fname=%s alpha=%ld\n",fname,tti->hasAlpha);

#ifdef verbose
   for(UINT row = 0; row < 23; ++row)
   {
      for(UINT col = 0; col < 5; ++col)
      {
         //printf("%x\n", *(UINT*)&(tti->texdata[(row * bitmapData->Stride / 4 + col)*tti->depth]));
         printf("%x\n", *(UINT*)&(tti->texdata[(row * tti->x + col)*4])); //tti->depth]));
      }
      printf("- - - - - - - - - - \n");
   }
#endif

   tti->filename = fname;
  // wrong: tti->status = TEX_NEEDSBINDING; //make this the last thing you set, because another thread is watching ready to bind
   // wrong - let the calling function set the status otherwise textures disappear sometimes


   bitmap->UnlockBits(bitmapData);
   delete bitmapData;
   delete bitmap;
   //shutdownImageLoader();  //we'll keep it loaded
   if(0)
   {
	   shutdownImageLoader();
	   loaded = 0;
   }

   return 1;

}
HBITMAP CDpiHelper::CreateDeviceFromLogicalImage(HBITMAP _In_ hImage, ImageScalingMode scalingMode, Color clrBackground)
{
    IfNullAssertRetNull(hImage, "No image given to convert");

    // Instead of doing HBITMAP resizing with StretchBlt from one memory DC into other memory DC and HALFTONE StretchBltMode
    // which uses nearest neighbor resize algorithm (fast but results in pixelation), we'll use a GdiPlus image to do the resize, 
    // which allows specifying the interpolation mode for the resize resulting in smoother result.
    VsUI::GdiplusImage gdiplusImage;

    // Attaching the bitmap uses Bitmap.FromHBITMAP which does not take ownership of the HBITMAP passed as argument.
    // DeleteObject still needs to be used on the hImage but that should happen after the Bitmap object is deleted or goes out of scope.
    // The caller will have to DeleteObject both the HBITMAP they passed in this function and the new HBITMAP we'll be returning when we detach the GDI+ Bitmap
    gdiplusImage.Attach(hImage);

#ifdef DEBUG
    static bool fDebugDPIHelperScaling = false;
    WCHAR rgTempFolder[MAX_PATH];
    static int imgIndex = 1;
    CStringW strFileName;
    CPath pathTempFile;

    if (fDebugDPIHelperScaling)
    {
        if (!GetTempPath(_countof(rgTempFolder), rgTempFolder))
            *rgTempFolder = '\0';
    
        strFileName.Format(_T("DPIHelper_%05d_Before.png"), imgIndex);

        pathTempFile.Combine(rgTempFolder, strFileName);
        gdiplusImage.Save(pathTempFile);
    }
#endif

    Bitmap* pBitmap = gdiplusImage.GetBitmap();
    PixelFormat format = pBitmap->GetPixelFormat();
    const Color *pclrActualBackground = &clrBackground; 
    InterpolationMode interpolationMode = GetInterpolationMode(scalingMode);
    ImageScalingMode actualScalingMode = GetActualScalingMode(scalingMode);

    if (actualScalingMode != ImageScalingMode::NearestNeighbor)
    {
        // Modify the image. If the image is 24bpp or lower, convert to 32bpp so we can use alpha values
        if (format != PixelFormat32bppARGB)
        {
            pBitmap->ConvertFormat(PixelFormat32bppARGB, DitherTypeNone, PaletteTypeCustom, nullptr/*ColorPalette*/, 0 /*alphaThresholdPercent - all opaque*/);
        }

        // Now that we have 32bpp image, let's play with the pixels
        // Detect magenta or near-green in the image and use that as background
        VsUI::GdiplusImage::ProcessBitmapBits(pBitmap, [&](ARGB * pPixelData) 
        {
            if (clrBackground.GetValue() != TransparentColor.GetValue())
            {
                if (*pPixelData == clrBackground.GetValue())
                {
                    *pPixelData = TransparentHaloColor.GetValue();
                    pclrActualBackground = &clrBackground;
                }
            }
            else
            {
                if (*pPixelData == MagentaColor.GetValue())
                {
                    *pPixelData = TransparentHaloColor.GetValue();
                    pclrActualBackground = &MagentaColor;
                }
                else if (*pPixelData == NearGreenColor.GetValue())
                {
                    *pPixelData = TransparentHaloColor.GetValue();
                    pclrActualBackground = &MagentaColor;
                }
            }
        });
    }

    // Convert the GdiPlus image if necessary
    LogicalToDeviceUnits(&gdiplusImage, scalingMode, TransparentHaloColor);

    // Get again the bitmap, after the resize
    pBitmap = gdiplusImage.GetBitmap();

    if (actualScalingMode != ImageScalingMode::NearestNeighbor)
    {
        // Now that the bitmap is scaled up, convert back the pixels. 
        // Anything that is not fully opaque, make it clrActualBackground
        VsUI::GdiplusImage::ProcessBitmapBits(pBitmap, [&](ARGB * pPixelData) 
        {
            if ((*pPixelData & ALPHA_MASK) != 0xFF000000)
            {
                *pPixelData = pclrActualBackground->GetValue();
            }
        });

        // Convert back to original format
        if (format != PixelFormat32bppARGB)
        {
            pBitmap->ConvertFormat(format, DitherTypeNone, PaletteTypeCustom, nullptr/*ColorPalette*/, 0 /*alphaThresholdPercent - all opaque*/);
        }
    }

#ifdef DEBUG
    if (fDebugDPIHelperScaling)
    {
        strFileName.Format(_T("DPIHelper_%05d_After.png"), imgIndex++);
        pathTempFile.Combine(rgTempFolder, strFileName);
        gdiplusImage.Save(pathTempFile);
    }
#endif
  
    // Get the converted image handle - this returns a new HBITMAP that will need to be deleted when no longer needed
    // Detach using TransparentColor (transparent-black). If the result bitmap is to be used with AlphaBlend, that function 
    // keeps the background if the transparent pixels are black
    HBITMAP hBmpResult = gdiplusImage.Detach( TransparentColor );

    // When the image has 32bpp RGB format, when we call GDI+ to return an HBITMAP for the image, the result is actually
    // an ARGB bitmap (with alpha bytes==0xFF instead of reserved=0x00). Many GDI functions work with it fine, but 
    // adding it to an imagelist with ImageList_AddMasked will produce the wrong result, because the clrTransparent color 
    // won't match any background pixels due to the alpha byte value. So we need to zero-out out those bytes... 
    // If the bitmap was scaled with a bicubic/bilinear interpolation, the colors are interpolated with the clrBackground 
    // which may be transparent, so the resultant image will have alpha channel of interest, and we'll return the image as is.
    if (format == PixelFormat32bppRGB)
    {
        BITMAP bmp = {0};
        if (GetObject(hBmpResult, sizeof(bmp), &bmp) == sizeof(bmp) && bmp.bmBits != nullptr)
        {
            RGBQUAD* pPixels = reinterpret_cast<RGBQUAD*>(bmp.bmBits);

            for (int i=0; i< bmp.bmWidth * bmp.bmHeight; i++)
            {
                pPixels[i].rgbReserved = 0;
            }
        }
    }

    // Return the created image
    return hBmpResult;
}
// Creates new GdiplusImage from logical to device units
unique_ptr<VsUI::GdiplusImage> CDpiHelper::CreateDeviceFromLogicalImage(_In_ VsUI::GdiplusImage* pImage, ImageScalingMode scalingMode, Color clrBackground)
{
    IfNullAssertRetNull(pImage, "No image given to convert");

    // Get the original/logical bitmap
    Bitmap* pBitmap = pImage->GetBitmap();
    IfNullAssertRetNull(pBitmap, "No image given to convert");
    
    // Create a memory image scaled for size
    int deviceWidth = LogicalToDeviceUnitsX(pBitmap->GetWidth());
    int deviceHeight = LogicalToDeviceUnitsY(pBitmap->GetHeight());
    
    unique_ptr<VsUI::GdiplusImage> pDeviceImage(new VsUI::GdiplusImage());
    pDeviceImage->Create( deviceWidth, deviceHeight, pBitmap->GetPixelFormat() );
       
    if (!pDeviceImage->IsLoaded())
    {
        VSFAIL("Failed to create scaled image, out of memory?");
        return nullptr;
    }
    
    // Get a Graphics object for the device image on which we can paint 
    unique_ptr<Graphics> pGraphics(pDeviceImage->GetGraphics());
    if (pGraphics.get() == nullptr)
    {
        VSFAIL("Failed to obtain image Graphics");
        return nullptr;
    }
    
    // Set the interpolation mode. 
    InterpolationMode interpolationMode = GetInterpolationMode(scalingMode);
    pGraphics->SetInterpolationMode(interpolationMode);
    
    // Clear the background (used when scaling mode is not nearest neighbor)
    pGraphics->Clear(clrBackground);
    
    // Calculate the destination rectangle: full available space, except when keeping the image unscaled and just adding a border
    RectF rectD(0, 0, (float)deviceWidth, (float)deviceHeight);
    if (scalingMode == ImageScalingMode::BorderOnly || (scalingMode == ImageScalingMode::Default && m_PreferredScalingMode == ImageScalingMode::BorderOnly))
    {
        rectD = RectF(0, 0, (float)pBitmap->GetWidth(), (float)pBitmap->GetHeight());
        rectD.Offset( (float)((deviceWidth - pBitmap->GetWidth()) / 2),  (float)((deviceHeight - pBitmap->GetHeight())/ 2) );
    }

    // Define the source rectangle
    RectF rectS(0, 0, (float)pBitmap->GetWidth(), (float)pBitmap->GetHeight());
   
    // Specify a source rectangle shifted by half of pixel to account for GDI+ considering the source origin the center of top-left pixel
    // Failing to do so will result in the right and bottom of the bitmap lines being interpolated with the graphics' background color,
    // and will appear black even if we cleared the background with transparent color. 
    // The apparition of these artifacts depends on the interpolation mode, on the dpi scaling factor, etc.
    // E.g. at 150% DPI, Bicubic produces them and NearestNeighbor is fine, but at 200% DPI NearestNeighbor also shows them.
    // Many articles on the web talk about this problem, e.g. http://www.codeproject.com/Articles/14884/BorderBug
    rectS.Offset(-0.5f, -0.5f);
    
    // Draw the scaled bitmap in the device image
    pGraphics->DrawImage(pBitmap, rectD, rectS.X, rectS.Y, rectS.Width, rectS.Height, UnitPixel);
    
    // Return the new image
    return pDeviceImage;
}
Example #6
0
void ToolFilter::activate()
{
	ChildCore *child = this->core->getActiveChild();
	if( child != NULL ){
		if( this->lastActivate == true && this->isLastActivate == false ){
			this->lastActivate = false;
			return;
		}

		ToolFilter::Info fi;
		Bitmap *source = NULL;
		if( child->getWorkspace()->getSelection() != NULL ){
			source = child->getWorkspace()->getSelectedProjection(NULL,COPCOP);
		}
		else {
			source = child->getWorkspace()->getSelectedLayer()->getRender();
			source = source->Clone(Rect(0,0,source->GetWidth(),source->GetHeight()),source->GetPixelFormat());
		}				

		fi.bmpSource = source;
		fi.bmpEffect = NULL;
		fi.bw = this->lastBw;
		fi.bwalpha = (this->lastAlpha &&
					  this->lastFilterId != ID_FILTER_OLDSTONE &&
					  this->lastFilterId != ID_FILTER_EDGETRACE );
		fi.smooth = true;
		fi.edgeTrace = (this->lastFilterId == ID_FILTER_EDGETRACE);

		fi.filterId = this->lastFilterId;
		fi.filterValue = this->lastFilterValue;
		fi.filterByValue = (this->lastFilterId != ID_FILTER_CUSTOM);

		fi.minVal = 0;
		switch(fi.filterId){
			case ID_FILTER_SHARPEN:
				fi.maxVal = SHARPENMAX;
				break;
			default:
				fi.maxVal = FILTERMAX;
				break;
		}

		if( fi.filterByValue == true )
			fi.matrix = ToolFilter::allocateMatrix(fi.filterId,fi.filterValue);
		else
			fi.matrix = this->lastCustomMatrix;

		int result = NO;
		if( this->lastActivate == false ){
			result = this->core->getDialogs()->showDialog(
														(LPCTSTR)IDD_FIL,
														(DLGPROC)Dialogs::processDlg_Fil,
														(LPARAM)&fi
														);
		}
		else {
			this->lastActivate = false;
			result = YES;
		}
		if( result == YES ){

			Point shift(0,0);
			Rect *bounds = NULL;

			if( child->getWorkspace()->getSelection() != NULL ){
				bounds = new Rect(0,0,0,0);
				child->getWorkspace()->getSelection()->GetBounds(bounds);

				fi.bmpSource = child->getWorkspace()->getSelectedLayer()->getRender();
			}
			else {
				int exw = (int)( floor(fi.matrix.mxw / 2.0) + 1 );
				int exh = (int)( floor(fi.matrix.mxh / 2.0) + 1 );

				shift.X = -exw;
				shift.Y = -exh;

				Bitmap *newsource = new Bitmap(
					source->GetWidth() + 2 * exw,
					source->GetHeight() + 2 * exh,
					source->GetPixelFormat());
				Graphics *g = Graphics::FromImage(newsource);
				g->DrawImage(source,exw,exh,source->GetWidth(),source->GetHeight());

				delete g;
				delete source;

				source = newsource;
				fi.bmpSource = newsource;
			}
			if( fi.filterByValue == true )
				this->lastFilterValue = fi.filterValue;
			else
				this->lastCustomMatrix = fi.matrix;
			this->lastBw = fi.bw;
			this->lastAlpha = fi.bwalpha;

			Rect newbounds = ToolFilter::applyFilter(&fi,bounds);

			if( child->getWorkspace()->getSelection() == NULL ){
				bounds = &newbounds;
				bounds->X += shift.X;
				bounds->Y += shift.Y;
			}

			child->getWorkspace()->getSelectedLayer()->applyEffect(
				fi.bmpEffect,
				bounds,
				this,
				fi.filterId);
			delete fi.bmpEffect;

			this->isLastActivate = true;

			child->getWorkspace()->updateToolws();
			child->getWorkspace()->update();
		}
		if( source != NULL )
			delete source;
	}
}
Example #7
0
Rect ToolFilter::applyFilter(ToolFilter::Info *fi, Rect *clip, bool once)
{
	Core::self->getGui()->setCursor(CURSOR_WAIT);

	int w = (int)( floor(fi->matrix.mxw / 2.0) );
	int h = (int)( floor(fi->matrix.mxh / 2.0) );

	int exw = fi->matrix.mxw + 1;
	int exh = fi->matrix.mxh + 1;

	UINT *src0, *bmp0;
	BitmapData srcData, bmpData;

	Bitmap *src = fi->bmpSource;
	Rect srcRect(0,0,src->GetWidth(),src->GetHeight());

	if( clip == NULL ){
		clip = &srcRect;
	}
	else {
		int maxx = max(clip->X - exw,0);
		int maxy = max(clip->Y - exh,0);
		int ext = 2;

		srcRect = Rect(
			maxx,
			maxy,
			min(clip->Width + ext * exw,(int)src->GetWidth() - maxx),
			min(clip->Height + ext * exh,(int)src->GetHeight() - maxy)
			);
	}

	int bmpWidth = clip->Width;
	int bmpHeight = clip->Height;
	if( fi->smooth == true ){
		bmpWidth += 4 * exw;
		bmpHeight += 4 * exh;
	}

	Bitmap *bmp = new Bitmap(
		bmpWidth,
		bmpHeight,
		src->GetPixelFormat()
		);
	Rect bmpRect(0,0,bmp->GetWidth(),bmp->GetHeight());

	src->LockBits(
			&srcRect,
			ImageLockModeRead,
			src->GetPixelFormat(),
			&srcData
			);
	bmp->LockBits(
			&bmpRect,
			ImageLockModeWrite,
			bmp->GetPixelFormat(),
			&bmpData
			);
	src0 = (UINT *)srcData.Scan0;
	bmp0 = (UINT *)bmpData.Scan0;

	int srcWidth = srcData.Width;
	int srcHeight = srcData.Height;

	for( int x = 0; x < bmpWidth; x++ ){
		for( int y = 0; y < bmpHeight; y++ ){
			bmp0[y * bmpData.Stride / 4 + x] = ToolFilter::filterPixel(fi,&srcData,x,y,w,h); 
		}
	}
	if( fi->edgeTrace == true && fi->filterValue > 0 ){
		ToolFilter::Matrix oldMatrix = fi->matrix;

		fi->matrix = ToolFilter::allocMatrixEdgetrace(fi->filterValue,1);
		for( int x = 0; x < bmpWidth; x++ ){
			for( int y = 0; y < bmpHeight; y++ ){
				bmp0[y * bmpData.Stride / 4 + x] += ToolFilter::filterPixel(fi,&srcData,x,y,w,h); 
			}
		}
		fi->matrix = ToolFilter::allocMatrixEdgetrace(fi->filterValue,2);
		for( int x = 0; x < bmpWidth; x++ ){
			for( int y = 0; y < bmpHeight; y++ ){
				bmp0[y * bmpData.Stride / 4 + x] += ToolFilter::filterPixel(fi,&srcData,x,y,w,h); 
			}
		}

		fi->matrix = oldMatrix;
	}
	src->UnlockBits(&srcData);
	bmp->UnlockBits(&bmpData);

	fi->bmpEffect = bmp;

	int refils = 0;
	switch(fi->filterId){
		case ID_FILTER_SHARPEN:
			if( fi->filterValue > SHARPENMAX/2 )
				refils = fi->filterValue - SHARPENMAX/2;
			break;
		case ID_FILTER_GAUSSIANBLUR:
			if( fi->filterValue > GAUSSMAX )
				refils = fi->filterValue - GAUSSMAX;
			break;
	}
	Bitmap *source = fi->bmpSource;

	if( refils > 0 && once == false ){
		for(int i = 0; i < refils; i++ ){
			fi->bmpSource = fi->bmpEffect;
			fi->bmpEffect = NULL;

			ToolFilter::applyFilter(fi,NULL,true);

			delete fi->bmpSource;
		}
	}
	fi->bmpSource = source;

	Rect gridClip(clip->X,clip->Y,clip->Width,clip->Height);

	clip->X -= exw;
	clip->Y -= exh;

	Core::self->getGui()->setCursor();

	return gridClip;
}
BOOL SavePngFile(HICON hIcon, LPCSTR strPngFile,int iOutWith = -1,int iOutHeight = -1)
{
	if (hIcon == NULL)
		return FALSE;

	ICONINFO icInfo = { 0 };
	if (!::GetIconInfo(hIcon, &icInfo))
		return FALSE;


	BITMAP bitmap; 
	GetObject(icInfo.hbmColor, sizeof(BITMAP), &bitmap);

	Bitmap* pBitmap = NULL;
	Bitmap* pWrapBitmap = NULL;
	if (bitmap.bmBitsPixel != 32) 
	{   
		pBitmap = Bitmap::FromHICON(hIcon); 
	} 
	else
	{
		pWrapBitmap = Bitmap::FromHBITMAP(icInfo.hbmColor, NULL);
		BitmapData bitmapData;
		Rect rcImage(0,0, pWrapBitmap->GetWidth(), pWrapBitmap->GetHeight());
		pWrapBitmap->LockBits(&rcImage, ImageLockModeRead, pWrapBitmap->GetPixelFormat(), &bitmapData); 

		pBitmap = new Bitmap(bitmapData.Width, bitmapData.Height, bitmapData.Stride, 
			PixelFormat32bppARGB, (BYTE*)bitmapData.Scan0);

		pWrapBitmap->UnlockBits(&bitmapData);

		Gdiplus::Color Bmpcolor;
		BOOL BmpcolorTag=TRUE;
		for (UINT bmpx=0;bmpx<pBitmap->GetWidth();bmpx++)
		{
			for (UINT bmpy=0;bmpy<pBitmap->GetHeight();bmpy++)
			{
				pBitmap->GetPixel(bmpx,bmpy,&Bmpcolor);
				if(Bmpcolor.GetA()!=0)
				{
					BmpcolorTag=FALSE;
					break;	
				}
			}
			if (BmpcolorTag==FALSE)
				break;
		}
		if (BmpcolorTag==TRUE)
		{
			delete pWrapBitmap;
			pWrapBitmap = NULL;
			delete pBitmap;
			pBitmap = NULL;
			pBitmap = Gdiplus::Bitmap::FromHICON(hIcon); 
		} 
	}

	DeleteObject(icInfo.hbmColor); 
	DeleteObject(icInfo.hbmMask);

	static bool GetPngCode = false;
	static CLSID pngid;
	if (!GetPngCode)
	{
		GetPngCode = true;
		GetEncoderClsid(L"image/png", &pngid);
	}

	if (iOutWith !=-1 && iOutHeight!=-1)
	{
		Bitmap *pStretched =  StretchBitmap(pBitmap,128,128);
		if (pStretched)
		{
			delete pBitmap; 
			pBitmap = pStretched;
		}
	}

	_bstr_t bstr(strPngFile);
	wstring wstrPng = (WCHAR*)bstr;
	Gdiplus::Status s = pBitmap->Save(wstrPng.c_str(),&pngid,NULL);
	delete pBitmap; 
	if (pWrapBitmap)
		delete pWrapBitmap;

	DeleteObject(icInfo.hbmColor); 
	DeleteObject(icInfo.hbmMask); 

	if (s==Gdiplus::Ok)
		return TRUE;

	return FALSE;
}