A compression method for image size and quality using GDI +

Source: Internet
Author: User

Today, my colleague asked me about the image compression algorithm. I think of a project I did about two or three years ago. It contains two compression algorithms: size and quality, and supports JPEG, bmp, and PNG formats. I will post this logic for your reference today. (For details, refer to the CSDN blog from breaksoftware)

Size Compression
Bool CompressImagePixel (const WCHAR * pszOriFilePath, const WCHAR * pszdestfilepha, UINT ulNewHeigth, UINT ulNewWidth) {// Initialize GDI +. gdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Status stat = GenericError; stat = GdiplusStartup (& gdiplusToken, & gdiplusStartupInput, NULL); if (OK! = Stat) {return false;} // reset the status stat = GenericError; // Get an image from the disk. image * pImage = new Image (pszOriFilePath); do {if (NULL = pImage) {break;} // obtain the length and width of UINT unOriHeight = pImage-> GetHeight (); UINT unOriWidth = pImage-> GetWidth (); do {CLSID encoderClsid; if (unOriWidth <1 | unOriHeight <1) {break;} // Get the CLSID of the JPEG encoder. if (! GetEncoderClsid (L "image/jpeg", & encoderClsid) {break;} REAL fSrcX = 0.0f; REAL fSrcY = 0.0f; REAL fSrcWidth = (REAL) unOriWidth; REAL fSrcHeight = (REAL) unOriHeight; RectF RectDest (0.0f, 0.0f, (REAL) Second, (REAL) ulNewHeigth); Bitmap * pTempBitmap = new Bitmap (ulNewWidth, ulNewHeigth ); graphics * graphics = NULL; do {if (! PTempBitmap) {break;} graphics = Graphics: FromImage (pTempBitmap); if (! Graphics) {break;} stat = graphics-> SetInterpolationMode (Gdiplus: InterpolationModeHighQuality); if (OK! = Stat) {break;} stat = graphics-> SetSmoothingMode (Gdiplus: SmoothingModeHighQuality); if (OK! = Stat) {break;} stat = graphics-> DrawImage (pImage, RectDest, fSrcX, fSrcY, fSrcWidth, fSrcHeight, UnitPixel, NULL, NULL); if (OK! = Stat) {break;} stat = pTempBitmap-> Save (pszdestfilepha, & encoderClsid, NULL); if (OK! = Stat) {break;} while (0); if (NULL! = Graphics) {delete graphics; graphics = NULL;} if (NULL! = PTempBitmap) {delete pTempBitmap; pTempBitmap = NULL ;}} while (0) ;}while (0); if (pImage) {delete pImage; pImage = NULL ;} gdiplusShutdown (gdiplusToken); return (OK = stat )? True: false );}
Quality Compression
Bool CompressImageQuality (const WCHAR * pszOriFilePath, const WCHAR * pszdestfilepha, ULONG quality) {// copy from http://msdn.microsoft.com/en-us/library/ms533844 (v = VS.85 ). aspx // Initialize GDI +. gdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Status stat = GenericError; stat = GdiplusStartup (& gdiplusToken, & gdiplusStartupInput, NULL); if (OK! = Stat) {return false;} // reset the status stat = GenericError; // Get an image from the disk. image * pImage = new Image (pszOriFilePath); do {if (NULL = pImage) {break;} // obtain the length and width of UINT ulHeight = pImage-> GetHeight (); UINT ulWidth = pImage-> GetWidth (); if (ulWidth <1 | ulHeight <1) {break;} // Get the CLSID of the JPEG encoder. CLSID encoderClsid; if (! GetEncoderClsid (L "image/jpeg", & encoderClsid) {break;} // The one EncoderParameter object has an array of values. // In this case, there is only one value (of type ULONG) // in the array. we will let this value vary from 0 to 100. encoderParameters encoderParameters; encoderParameters. count = 1; encoderParameters. parameter [0]. guid = EncoderQuality; encoderParameters. parameter [0]. type = EncoderP ArameterValueTypeLong; encoderParameters. parameter [0]. numberOfValues = 1; encoderParameters. parameter [0]. value = & quality; stat = pImage-> Save (pszdestfilepha, & encoderClsid, & encoderParameters) ;}while (0); if (pImage) {delete pImage; pImage = NULL ;} gdiplusShutdown (gdiplusToken); return (stat = OK )? True: false );}
The two algorithms are associated with a function GetEncoderClsid, which is implemented as follows:
#include 
 
  #include 
  
   #pragma comment( lib, "GdiPlus.lib" )using namespace Gdiplus;bool GetEncoderClsid(const WCHAR* pszFormat, CLSID* pClsid){    UINT  unNum = 0;          // number of image encoders    UINT  unSize = 0;         // size of the image encoder array in bytes    ImageCodecInfo* pImageCodecInfo = NULL;    // How many encoders are there?    // How big (in bytes) is the array of all ImageCodecInfo objects?    GetImageEncodersSize( &unNum, &unSize );    if ( 0 == unSize ) {        return false;  // Failure    }    // Create a buffer large enough to hold the array of ImageCodecInfo    // objects that will be returned by GetImageEncoders.    pImageCodecInfo = (ImageCodecInfo*)( malloc(unSize) );    if ( !pImageCodecInfo ) {        return false;  // Failure    }    // GetImageEncoders creates an array of ImageCodecInfo objects    // and copies that array into a previously allocated buffer.     // The third argument, imageCodecInfos, is a pointer to that buffer.     GetImageEncoders( unNum, unSize, pImageCodecInfo );    for ( UINT j = 0; j < unNum; ++j ) {        if ( wcscmp( pImageCodecInfo[j].MimeType, pszFormat ) == 0 ) {            *pClsid = pImageCodecInfo[j].Clsid;            free(pImageCodecInfo);            pImageCodecInfo = NULL;            return true;  // Success        }        }    free( pImageCodecInfo );    pImageCodecInfo = NULL;    return false;  // Failure}
  
 
In my test code, the file name contains A as the source file, and the file name contains B as the size compression algorithm. The file name contains C as the quality compression (the size remains unchanged) the file obtained by the algorithm. The test code is
int _tmain(int argc, _TCHAR* argv[]){    CompressImagePixel( L"1A.jpg", L"1B.jpg",  100, 100 );    CompressImageQuality( L"1A.jpg", L"1C.jpg", 30 );    CompressImagePixel( L"2A.png", L"2B.jpg",  100, 100 );    CompressImageQuality( L"2A.png", L"2C.jpg", 30 );    CompressImagePixel( L"3A.bmp", L"3B.jpg",  100, 100 );    CompressImageQuality( L"3A.bmp", L"3C.jpg", 30 );return 0;}
The compression result is

From the compression results, the size compression is stable and the quality compression is unstable. If you want to control the file size through the compression algorithm, you need to combine these two methods. However, this quality compression algorithm cannot be abused. Under certain circumstances, this compression will increase the size of the file space.
Add the project code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.