ImageStone is a powerful C++ class library for image manipulation. It is written in pure C++ and is easily to portable. Its features include load/save (supports BMP, GIF, JPG, PNG, TIF, ICO, TGA, PCX, PSD...), display, histogram, undo/redo, and image transformation with over 100 predefined effects.
ImageStone is free. You can use the code however you want (free or commercial), as long as you don't claim it as your own. (If you use it in your product, I hope I could be notified.)
It's extremely easy, all you need to do is add #include "ImageStone.h"
at the beginning of your source code. If you are using ImageStone in a MFC project, just add this include line at the end of StdAfx.h file.
The most basic and the most important class is FCObjImage
, let's learn how to use it.
// for Windows : ImageStone use GDI+ to load/save image, Jpg/Png/Gif/Bmp/Tga/Tif be supported // for Linux : Only Bmp/Tga be supported, but you can set FreeImage handler to support more. FCObjImage img ; img.Load ("test.jpg") ; if (!img.IsValidImage()) { assert(false) ; return false ; } // print image's information : width, height, bit per pixel printf ("image's width : %d", img.Width()) ; printf ("image's height : %d", img.Height()) ; printf ("image's bpp : %d", img.ColorBits()) ; // Load/Save function determine image's format by file's ext name // save image as jpeg file, jpg's quality set 90 (ranges from 1 to 99) img.Save ("save.jpg", 90) ; img.Save ("save.png") ; img.Save ("save.tif") ; // Another way to set quality FCImageProperty prop ; prop.SetPropertyValue (IMAGE_TAG_JPEG_QUALITY, "90") ; img.Save ("save.jpg", prop) ;
// Load image into memory char * p = 0 ; int n = 0 ; FCOXOHelper::LoadFileToBuffer ("test.jpg", p, n) ; FCObjImage img ; img.Load (p, n, IMG_JPG) ; delete[] p ; // this line demonstrate how to determine image's format by file's ext name IMAGE_TYPE t = FCObjImage::GetImageHandleFactory()->QueryImageFileType("test.jpg");
// Load image into memory char * p = 0 ; int n = 0 ; FCOXOHelper::LoadFileToBuffer ("test.bmp", p, n) ; p += sizeof(BITMAPFILEHEADER) ; // now p point to a DIB stream FCObjImage img ; img.LoadDIBStream (p, n) ; delete[] p ;
// Load image from local exe file FCObjImage img ; FCWin32::LoadImageRes (img, MAKEINTRESOURCE(nID), TEXT("JPG"), IMG_JPG) ; // Load image from DLL's resource HMODULE hDll = LoadLibrary (TEXT("ResDll.dll")) ; FCWin32::LoadImageRes (img, MAKEINTRESOURCE(nID), TEXT("JPG"), IMG_JPG, hDll) ; // Load image from standard BITMAP resource FCWin32::LoadImageBitmapRes (img, MAKEINTRESOURCE(nID)) ;
// change to FreeImage library load/save image // more detail refer to example 005 FCObjImage::SetImageHandleFactory (new FCImageHandleFactory_FreeImage) ; img.Load ("test.jpg") ; // change to GDI+ load/save image FCObjImage::SetImageHandleFactory (new FCImageHandleFactory_Gdiplus) ; img.Load ("test.jpg") ;
// use FreeImage to load/save PSD/PCX image class CMyImageFactory : public FCImageHandleFactory { protected: virtual FCImageHandleBase* CreateImageHandle (IMAGE_TYPE imgType) { switch (imgType) { case IMG_BMP : return new FCImageHandle_Bmp ; case IMG_TGA : return new FCImageHandle_Tga ; case IMG_JPG : return new FCImageHandle_Gdiplus ; case IMG_GIF : return new FCImageHandle_Gdiplus ; case IMG_TIF : return new FCImageHandle_Gdiplus ; case IMG_PNG : return new FCImageHandle_Gdiplus ; case IMG_PCX : return new FCImageHandle_FreeImage ; case IMG_PSD : return new FCImageHandle_FreeImage ; } return 0 ; } // protected avoid user delete object. virtual ~CMyImageFactory() {} }; // use our custom factory to read/write image FCObjImage::SetImageHandleFactory (new CMyImageFactory) ; FCObjImage img ; img.Load ("test.jpg") ;
FCObjMultiFrame img ; img.Load ("test.gif") ; img.GetFrame(0)->Save ("001.jpg") ; img.GetFrame(1)->Save ("001.jpg") ; ...
FCObjImage img ; FCImageProperty prop ; img.Load ("test.jpg", &prop) ; // get camera ISO speed std::string m = prop.QueryPropertyValue (IMAGE_TAG_EXIF_ISOSpeed) ; // get camera equip model std::string n = prop.QueryPropertyValue (IMAGE_TAG_EquipModel) ;
FCObjImage img ; // capture current screen RECT rc = {0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)} ; FCWin32::CaptureScreen (img, rc) ; // Draw image (no stretch) where top-left at (0,0) of hdc FCWin32::DrawImage (img, hdc, 0, 0) ; // Stretch image on region of hdc RECT rcOnDC = {100, 100, 200, 200} ; FCWin32::DrawImage (img, hdc, rcOnDC) ; // Stretch image on central of hdc's region and keeping image's aspect FCWin32::DrawImageAspect (img, hdc, rcOnDC) ; // Stretch regionof image on region of hdc RECT rcImg = {20, 20, 50, 50} ; FCWin32::DrawImage (img, hdc, rcOnDC, rcImg) ;
FCObjImage img ; img.Load ("test.jpg") ; // copy image to clipboard FCWin32::CopyToClipboard (img) ; // get image in clipboard FCWin32::GetClipboardImage (img) ;
// create HBITMAP from FCObjImage object FCObjImage img ; img.Load ("test.jpg") ; HBITMAP h = FCWin32::CreateDDBHandle (img) ; // create FCObjImage object from HBITMAP FCWin32::CreateImageFromDDB (h, img) ;
// create GDI+ Bitmap from FCObjImage object FCObjImage img ; img.Load ("test.jpg") ; Gdiplus::Bitmap * pBmp = FCWin32::GDIPlus_CreateBitmap(img) ; delete pBmp ; // create FCObjImage object from GDI+ Bitmap FCWin32::GDIPlus_LoadBitmap (*pBmp, img) ;
FCObjImage img ; img.Load ("test.jpg") ; // resize (smooth) image img.Stretch (nWidth, nHeight) ; img.Stretch_Smooth (nWidth, nHeight) ; // Use SinglePixelProcessProc interface to process // image, there are over 100 pre-implemented effect, // please refer to class derived from FCInterface_PixelProcess FCPixelRotate aCmd (37) ; img.SinglePixelProcessProc (aCmd) ; FCPixelBrightness aCmd (150) ; // 150% img.SinglePixelProcessProc (aCmd) ; FCPixelMosaic aCmd(5) ; img.SinglePixelProcessProc (aCmd) ; FCPixelOilPaint aCmd (3) ; img.SinglePixelProcessProc (aCmd) ;
// our processor : change pixel's RGB value class CMyPixelProcessor : public FCSinglePixelProcessBase { public: CMyPixelProcessor (int nR, int nG, int nB) : m_R(nR), m_G(nG), m_B(nB) {} private: virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel) { PCL_B(pPixel) = FClamp0255 (PCL_B(pPixel) + m_B) ; PCL_G(pPixel) = FClamp0255 (PCL_G(pPixel) + m_G) ; PCL_R(pPixel) = FClamp0255 (PCL_R(pPixel) + m_R) ; } int m_R, m_G, m_B ; }; // this class has the same function to upper // class, but implement other class class CMyImageProcessor : public FCPixelWholeImageBase { public: CMyPixelProcessor (int nR, int nG, int nB) : m_R(nR), m_G(nG), m_B(nB) {} private: virtual void ProcessWholeImage (FCObjImage* pImg, FCObjProgress* pProgress) { for (int y=0 ; y < pImg->Height() ; y++) { for (int x=0 ; x < pImg->Width() ; x++) { BYTE * p = pImg->GetBits(x,y) ; PCL_B(p) = FClamp0255 (PCL_B(p) + m_B) ; PCL_G(p) = FClamp0255 (PCL_G(p) + m_G) ; PCL_R(p) = FClamp0255 (PCL_R(p) + m_R) ; } if (pProgress) pProgress->SetProgress (100 * y / pImg->Height()) ; } } int m_R, m_G, m_B ; }; // use our custom processor FCObjImage img ; img.Load ("test.jpg") ; CMyPixelProcessor aCmd (20, 20, 20) ; img.SinglePixelProcessProc (aCmd) ; CMyImageProcessor aCmd (20, 20, 20) ; img.SinglePixelProcessProc (aCmd) ;
FCObjImage img ; img.Load ("c:\\test.jpg") ; // now we create text layer FCObjTextLayer imgT ; PACK_TextLayer tp ; tp.m_bAddShadow = false ; tp.m_bAntiAliased = true ; tp.m_bBold = true ; tp.m_bItalic = true ; tp.m_crFont = PCL_RGBA(0,0,255) ; tp.m_nFontSize = 128 ; tp.m_strFace = "Arial" ; tp.m_strText = "Hello" ; FCWin32::CreateTextLayer_GDIPlus (imgT, tp) ; // now we have create text image, additional // we can add some affect on it, such as gradient color POINT pt1={0,0}, pt2={0,50} ; FCPixelGradientLine aCmd (pt1, pt2, PCL_RGBA(0,0,255), FCColor::crWhite()) ; imgT.SinglePixelProcessProc (aCmd) ; // blend text layer on image RECT rc = {0, 0, imgT.Width(), imgT.Height()} ; img.AlphaBlend (imgT, rc, rc, 100) ;
Contact information of the author, Fu Li: