A question about GDI+
-
Hi there, I want to rotate an image and then save it in a file using GDI+. Is that possible? I don't want to draw the rotated image. Thanks!
Hi if you want to make a simple rotation (90, 180, 270 or flip), you can use : pBmp->RotateFlip(Rotate180FlipNone); // Rotate180FlipNone is an exemple if you want to rotate it, use this Bitmap* Rotate ( Bitmap* pSrcBmp, REAL rRot ) { int w = pSrcBmp->GetWidth(); int h = pSrcBmp->GetHeight(); Bitmap* pDstBmp = new Bitmap( (w+h)*2, (w+h)*2, PixelFormat32bppARGB ); // (w+h)*2 max width and height, you can optimize it(?) Graphics graphics(pDstBmp); graphics.Clear(Color(0,255,255,255)); Pen pen(Color(255, 255, 0, 0)); graphics.TranslateTransform((REAL)w+h, (REAL)w+h); graphics.RotateTransform(rRot); graphics.DrawImage(pSrcBmp, 0, 0); return pDestBmp; } save this image with { GetCodecClsid(L"image/tiff", &mClsid); // you can use L"image/jpeg", L"image/gif", ... pBmp->Save(L"img.tif", &mClsid); } int GetCodecClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; return j; // Success } } // for return -1; // Failure }
-
Hi if you want to make a simple rotation (90, 180, 270 or flip), you can use : pBmp->RotateFlip(Rotate180FlipNone); // Rotate180FlipNone is an exemple if you want to rotate it, use this Bitmap* Rotate ( Bitmap* pSrcBmp, REAL rRot ) { int w = pSrcBmp->GetWidth(); int h = pSrcBmp->GetHeight(); Bitmap* pDstBmp = new Bitmap( (w+h)*2, (w+h)*2, PixelFormat32bppARGB ); // (w+h)*2 max width and height, you can optimize it(?) Graphics graphics(pDstBmp); graphics.Clear(Color(0,255,255,255)); Pen pen(Color(255, 255, 0, 0)); graphics.TranslateTransform((REAL)w+h, (REAL)w+h); graphics.RotateTransform(rRot); graphics.DrawImage(pSrcBmp, 0, 0); return pDestBmp; } save this image with { GetCodecClsid(L"image/tiff", &mClsid); // you can use L"image/jpeg", L"image/gif", ... pBmp->Save(L"img.tif", &mClsid); } int GetCodecClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; return j; // Success } } // for return -1; // Failure }
-
Hi if you want to make a simple rotation (90, 180, 270 or flip), you can use : pBmp->RotateFlip(Rotate180FlipNone); // Rotate180FlipNone is an exemple if you want to rotate it, use this Bitmap* Rotate ( Bitmap* pSrcBmp, REAL rRot ) { int w = pSrcBmp->GetWidth(); int h = pSrcBmp->GetHeight(); Bitmap* pDstBmp = new Bitmap( (w+h)*2, (w+h)*2, PixelFormat32bppARGB ); // (w+h)*2 max width and height, you can optimize it(?) Graphics graphics(pDstBmp); graphics.Clear(Color(0,255,255,255)); Pen pen(Color(255, 255, 0, 0)); graphics.TranslateTransform((REAL)w+h, (REAL)w+h); graphics.RotateTransform(rRot); graphics.DrawImage(pSrcBmp, 0, 0); return pDestBmp; } save this image with { GetCodecClsid(L"image/tiff", &mClsid); // you can use L"image/jpeg", L"image/gif", ... pBmp->Save(L"img.tif", &mClsid); } int GetCodecClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; return j; // Success } } // for return -1; // Failure }
My source file is tif, grayscale, PixelFormat8bppIndexed. I can't create Graphics object from image with such pixel format. So I have to use PixelFormat32bppARGB for example. Can I convert that image to image with 8 bpp indexed pixel format before I save it in a file? I am concern about the size of the output file. Thanks!
-
My source file is tif, grayscale, PixelFormat8bppIndexed. I can't create Graphics object from image with such pixel format. So I have to use PixelFormat32bppARGB for example. Can I convert that image to image with 8 bpp indexed pixel format before I save it in a file? I am concern about the size of the output file. Thanks!
you can use this code (with some -fast- asm) { Bitmap* pDstBmp = Convert_Bmp32_Bmp8( pSrcBmp ); } Bitmap* CMdiPrjDoc::Convert_Bmp32_Bmp8( Bitmap *mBmpSrc ) { int x = mBmpSrc->GetWidth(); int y = mBmpSrc->GetHeight(); Bitmap* mBmpDest = new Bitmap( x, y, PixelFormat8bppIndexed ); SetPaletteGrayScale(mBmpDest); BitmapData bitmapData, tBitmapData; Rect rect(0, 0, x, y); BYTE *pixels; DWORD *tPixels; mBmpDest->LockBits( &rect, ImageLockModeWrite, PixelFormat8bppIndexed, &bitmapData); mBmpSrc->LockBits( &rect, ImageLockModeRead, PixelFormat32bppARGB, &tBitmapData); pixels = (BYTE*)bitmapData.Scan0; tPixels = (DWORD*)tBitmapData.Scan0; DWORD rD; int iLineJmp, iTLineJmp; for(UINT yi=0; yiUnlockBits(&tBitmapData); mBmpDest->UnlockBits(&bitmapData); return mBmpDest; } void SetPaletteGrayScale(Bitmap* pBmp) { if(!pBmp) return; ColorPalette* cp = (ColorPalette*)malloc(sizeof(ColorPalette)+256*4); cp->Flags = PaletteFlagsGrayScale; cp->Count = 256; DWORD argb; BYTE b; for(int i=0; i<256; i++) { b = i; _asm { mov ah, 255 mov al, b shl eax, 16 mov ah, b mov al, b mov argb, eax } cp->Entries[i] = argb; } pBmp->SetPalette(cp); free (cp); }