• Welcome to Jose's Read Only Forum 2023.
 

GDI+: EncoderParameters Structure

Started by José Roca, June 23, 2008, 03:02:26 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
Setting JPEG Compression Level



To specify the compression level when you save a JPEG image, initialize an EncoderParameters structure and pass the address of that object to the function. Initialize the EncoderParameters structure so that it has an array consisting of one EncoderParameter structure. Initialize that one EncoderParameter structure so that its Value member points to a DWORD value from 0 through 100. Set the Guid member of the EncoderParameter structure to $EncoderQuality.

The following console application saves three JPEG images, each with a different quality level. A quality level of 0 corresponds to the greatest compression, and a quality level of 100 corresponds to the least compression.

C++


#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid);  // helper function

INT main()
{
   // Initialize GDI+.
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   CLSID             encoderClsid;
   EncoderParameters encoderParameters;
   ULONG             quality;
   Status            stat;

   // Get an image from the disk.
   Image* image = new Image(L"Shapes.bmp");

   // Get the CLSID of the JPEG encoder.
   GetEncoderClsid(L"image/jpeg", &encoderClsid);

   // Before we call Image::Save, we must initialize an
   // EncoderParameters object. The EncoderParameters object
   // has an array of EncoderParameter objects. In this
   // case, there is only one EncoderParameter object in the array.
   // 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.Count = 1;
   encoderParameters.Parameter[0].Guid = EncoderQuality;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;

   // Save the image as a JPEG with quality level 0.
   quality = 0;
   encoderParameters.Parameter[0].Value = &quality;
   stat = image->Save(L"Shapes001.jpg", &encoderClsid, &encoderParameters);

   if(stat == Ok)
      wprintf(L"%s saved successfully.\n", L"Shapes001.jpg");
   else
      wprintf(L"%d  Attempt to save %s failed.\n", stat, L"Shapes001.jpg");

   // Save the image as a JPEG with quality level 50.
   quality = 50;
   encoderParameters.Parameter[0].Value = &quality;
   stat = image->Save(L"Shapes050.jpg", &encoderClsid, &encoderParameters);

   if(stat == Ok)
      wprintf(L"%s saved successfully.\n", L"Shapes050.jpg");
   else
      wprintf(L"%d  Attempt to save %s failed.\n", stat, L"Shapes050.jpg");

      // Save the image as a JPEG with quality level 100.
   quality = 100;
   encoderParameters.Parameter[0].Value = &quality;
   stat = image->Save(L"Shapes100.jpg", &encoderClsid, &encoderParameters);

   if(stat == Ok)
      wprintf(L"%s saved successfully.\n", L"Shapes100.jpg");
   else
      wprintf(L"%d  Attempt to save %s failed.\n", stat, L"Shapes100.jpg");

   delete image;
   GdiplusShutdown(gdiplusToken);
   return 0;
}


PowerBASIC

The main function relies on the helper function GdiPlusGetEncoderClsid to retrieve the guid of the TIFF encoder.


#COMPILE EXE
#DIM ALL
#INCLUDE "GDIPLUS.INC"
#INCLUDE "GDIPUTILS.INC"

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   LOCAL hStatus AS LONG
   LOCAL token AS DWORD
   LOCAL StartupInput AS GdiplusStartupInput
   LOCAL EncoderClsid AS GUID
   LOCAL pImage AS DWORD
   LOCAL eps AS EncoderParameters
   LOCAL ep AS EncoderParameter
   LOCAL dwQuality AS DWORD
   LOCAL strFileName AS STRING

   ' // Initialize GDI+
   StartupInput.GdiplusVersion = 1
   hStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
   IF hStatus THEN
      PRINT "Error initializing GDI+"
      EXIT FUNCTION
   END IF

   strFileName = UCODE$("Shapes.bmp")
   hStatus = GdipLoadImageFromFile(STRPTR(strFileName), pImage)

   ' // Get the CLSID of the JPEG encoder.
   EncoderClsid = GUID$(GdiPlusGetEncoderClsid("image/jpeg"))

   ' // Before we call GdipSaveImageToFile, we must initialize an
   ' // EncoderParameters structure The EncoderParameters structure
   ' // has an array of EncoderParameter structures In this
   ' // case, there is only one EncoderParameter structure in the array.
   ' // The one EncoderParameter structure has an array of values.
   ' // In this case, there is only one value (of type DWORD)
   ' // in the array. We will let this value vary from 0 to 100.

   eps.count = 1
   eps.Parameter(0).pGuid = $EncoderQuality
   eps.Parameter(0).dwType = %EncoderParameterValueTypeLong
   eps.Parameter(0).NumberOfValues = 1

   ' // Save the image as a JPEG with quality level 0.
   dwQuality = 0
   eps.Parameter(0).Value = VARPTR(dwQuality)
   strFileName = UCODE$("Shapes001.jpg")
   hStatus = GdipSaveImageToFile(pImage, STRPTR(strFileName), EncoderClsid, eps)
   IF hStatus = %StatusOk THEN PRINT "Shapes001.jpg saved successfully"

   ' // Save the image as a JPEG with quality level 50.
   dwQuality = 50
   eps.Parameter(0).Value = VARPTR(dwQuality)
   strFileName = UCODE$("Shapes050.jpg")
   hStatus = GdipSaveImageToFile(pImage, STRPTR(strFileName), EncoderClsid, eps)
   IF hStatus = %StatusOk THEN PRINT "Shapes050.jpg saved successfully"

   ' // Save the image as a JPEG with quality level 100.
   dwQuality = 100
   eps.Parameter(0).Value = VARPTR(dwQuality)
   strFileName = UCODE$("Shapes100.jpg")
   hStatus = GdipSaveImageToFile(pImage, STRPTR(strFileName), EncoderClsid, eps)
   IF hStatus = %StatusOk THEN PRINT "Shapes100.jpg saved successfully"

   ' // Cleanup
   IF pImage THEN GdipDisposeImage(pImage)

   ' // Shutdown GDI+
   GdiplusShutdown token

   WAITKEY$

END FUNCTION
' ========================================================================================


José Roca

#1
 
This example demonstrates how to set the compression and color depth when converting an image to the TIFF format. The EncoderParameters structure has two members, a dword with the number of EncoderParameter structures and an array of EncoderParameter structures. As PowerBASIC doesn't allow structures with dynamic arrays, an alternative is to build a buffer to hold the data and pass a pointer to this buffer to the GdipSaveImageToFile function.

Example:


#COMPILE EXE
#DIM ALL
#INCLUDE "GDIPLUS.INC"
#INCLUDE "GDIPUTILS.INC"

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   LOCAL hStatus AS LONG
   LOCAL token AS DWORD
   LOCAL StartupInput AS GdiplusStartupInput
   LOCAL s AS STRING
   LOCAL EncoderClsid AS GUID
   LOCAL pImage AS DWORD
   LOCAL LoadFlName AS STRING
   LOCAL SaveFlName AS STRING
   LOCAL ep1 AS EncoderParameter
   LOCAL ep2 AS EncoderParameter
   LOCAL strEncoderParameters AS STRING
   LOCAL Compression AS LONG
   LOCAL ColorDepth AS LONG

   ' --> Change as needed
   LoadFlName = UCODE$("RYDER_Winona_01.jpg")
   SaveFlName = UCODE$("RYDER_Winona_01.tiff")

   ' Fill and EncoderParameter structure with the compression
   Compression = %EncoderValueCompressionLZW
   ep1.pGUID = $EncoderCompression
   ep1.NumberOfValues = 1
   ep1.dwType = %EncoderParameterValueTypeLong
   ep1.value = VARPTR(Compression)

   ' Fill and EncoderParameter structure wuth the color depth
   ColorDepth = 24  ' 24-bits color depth
   ep2.pGUID = $EncoderColorDepth
   ep2.NumberOfValues = 1
   ep2.dwType = %EncoderParameterValueTypeLong
   ep2.value = VARPTR(ColorDepth)

   ' Build an EncoderParameters structure using an string
   strEncoderParameters = MKDWD$(2) & ep1 & ep2

   ' Initialize GDI+
   StartupInput.GdiplusVersion = 1
   hStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
   IF hStatus THEN
      MSGBOX "Error initializing GDI+"
      EXIT FUNCTION
   END IF

   ' Retrieve the encoder clsid
   s = GdiPlusGetEncoderClsid("image/tiff")
   IF s = "" THEN
      MSGBOX "Encoder not installed"
      GOTO Terminate
   END IF
   EncoderClsid = GUID$(s)

   ' Load image from file
   hStatus = GdipLoadImageFromFile(STRPTR(LoadFlName), pImage)
   IF hStatus THEN
      MSGBOX "GdipLoadImageFromFile - Failure, status = " & STR$(hStatus)
      GOTO Terminate
   END IF

   ' Convert and save the image to file
   IF pImage THEN
      hStatus = GdipSaveImageToFile(pImage, STRPTR(SaveFlName), EncoderClsid, BYVAL STRPTR(strEncoderParameters))
      IF hStatus THEN
         MSGBOX "GdipSaveImageToFile - Failure, status = " & STR$(hStatus)
      ELSE
         MSGBOX "Image converted"
      END IF
      ' Dispose the image
      hStatus = GdipDisposeImage(pImage)
   END IF

Terminate:

   ' Shutdown GDI+
   GdiplusShutdown token

END FUNCTION
' ========================================================================================