Delen via


Verliesloze transformatie van een JPEG-afbeelding

Wanneer u een JPEG-afbeelding comprimeert, gaat een deel van de informatie in de afbeelding verloren. Als u een JPEG-bestand opent, de afbeelding wijzigt en opslaat in een ander JPEG-bestand, neemt de kwaliteit af. Als u dat proces vaak herhaalt, ziet u een aanzienlijke afname van de beeldkwaliteit.

Omdat JPEG een van de populairste afbeeldingsindelingen op internet is en omdat mensen vaak JPEG-afbeeldingen willen wijzigen, biedt GDI+ de volgende transformaties die kunnen worden uitgevoerd op JPEG-afbeeldingen zonder verlies van informatie:

  • 90 graden draaien
  • 180 graden draaien
  • 270 graden draaien
  • Horizontaal spiegelen
  • Verticaal spiegelen

U kunt een van de transformaties uit de voorgaande lijst toepassen wanneer u de methode Opslaan van een Afbeelding-object aanroept. Als aan de volgende voorwaarden wordt voldaan, wordt de transformatie voortgezet zonder gegevensverlies:

  • Het bestand dat wordt gebruikt voor het maken van de afbeelding object is een JPEG-bestand.
  • De breedte en hoogte van de afbeelding zijn beide veelvouden van 16.

Als de breedte en hoogte van de afbeelding niet beide veelvouden van 16 zijn, doet GDI+ het beste om de beeldkwaliteit te behouden wanneer u een van de draaiings- of spiegelingstransformaties toepast die worden weergegeven in de voorgaande lijst.

Als u een JPEG-afbeelding wilt transformeren, initialiseert u een EncoderParameters--object en geeft u het adres van dat object door aan de methode Opslaan van de klasse Afbeelding. Initialiseer het EncoderParameters-object, zodat het een matrix bevat die bestaat uit één EncoderParameter--object. Initialiseer die ene EncoderParameter object zodat het waarde lid verwijst naar een ULONG--variabele die een van de volgende elementen van de opsomming EncoderValue bevat:

  • EncoderValueTransformRotate90,
  • EncoderValueTransformRotate180,
  • EncoderValueTransformRotate270,
  • EncoderValueTransformFlipHorizontal,
  • EncoderValueTransformFlipVertical

Stel het Guid- lid van het EncoderParameter--object in op EncoderTransformation.

De volgende consoletoepassing maakt een Image-object van een JPEG-bestand en slaat de afbeelding vervolgens op in een nieuw bestand. Tijdens het opslaan wordt de afbeelding 90 graden gedraaid. Als de breedte en hoogte van de afbeelding beide veelvouden van 16 zijn, veroorzaakt het proces van draaien en opslaan van de afbeelding geen verlies van informatie.

De hoofdfunctie is afhankelijk van de helperfunctie GetEncoderClsid, die wordt weergegeven in De klasse-id ophalen voor een encoder.

#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             transformation;
   UINT              width;
   UINT              height;
   Status            stat;

   // Get a JPEG image from the disk.
   Image* image = new Image(L"Shapes.jpg");

   // Determine whether the width and height of the image 
   // are multiples of 16.
   width = image->GetWidth();
   height = image->GetHeight();

   printf("The width of the image is %u", width);
   if(width / 16.0 - width / 16 == 0)
      printf(", which is a multiple of 16.\n");
   else
      printf(", which is not a multiple of 16.\n");

   printf("The height of the image is %u", height);
   if(height / 16.0 - height / 16 == 0)
      printf(", which is a multiple of 16.\n");
   else
      printf(", which is not a multiple of 16.\n");

   // 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 set that value to EncoderValueTransformRotate90.

   encoderParameters.Count = 1;
   encoderParameters.Parameter[0].Guid = EncoderTransformation;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;

   // Rotate and save the image.
   transformation = EncoderValueTransformRotate90;
   encoderParameters.Parameter[0].Value = &transformation;
   stat = image->Save(L"ShapesR90.jpg", &encoderClsid, &encoderParameters);

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

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