Trasformazione di un'immagine JPEG senza perdita di dati
Quando si comprime un'immagine JPEG, alcune delle informazioni nell'immagine vengono perse. Se si apre un file JPEG, modificare l'immagine e salvarla in un altro file JPEG, la qualità verrà ridotta. Se si ripete il processo molte volte, si noterà una riduzione sostanziale della qualità dell'immagine.
Poiché JPEG è uno dei formati di immagine più diffusi sul Web e poiché le persone spesso amano modificare le immagini JPEG, GDI+ fornisce le trasformazioni seguenti che possono essere eseguite nelle immagini JPEG senza perdita di informazioni:
- Ruotare 90 gradi
- Ruotare 180 gradi
- Ruotare 270 gradi
- Capovolgi orizzontalmente
- Capovolgi verticalmente
È possibile applicare una delle trasformazioni visualizzate nell'elenco precedente quando si chiama il metodo Save di un oggetto Image . Se vengono soddisfatte le condizioni seguenti, la trasformazione procederà senza perdita di informazioni:
- Il file usato per costruire l'oggetto Image è un file JPEG.
- La larghezza e l'altezza dell'immagine sono entrambi più di 16.
Se la larghezza e l'altezza dell'immagine non sono entrambe più di 16, GDI+ farà il meglio per mantenere la qualità dell'immagine quando si applica una delle trasformazioni di rotazione o scorrimento visualizzate nell'elenco precedente.
Per trasformare un'immagine JPEG, inizializzare un oggetto EncoderParameters e passare l'indirizzo di tale oggetto al metodo Save della classe Image . Inizializzare l'oggetto EncoderParameters in modo che disponga di una matrice costituita da un oggetto EncoderParameter . Inizializzare l'oggetto EncoderParameter in modo che il relativo membro Value punti a una variabile ULONG che contiene uno degli elementi seguenti dell'enumerazione EncoderValue :
- EncoderValueTransformRotate90,
- EncoderValueTransformRotate180,
- EncoderValueTransformRotate270,
- EncoderValueTransformFlipHorizontal,
- EncoderValueTransformFlipVertical
Impostare il membro Guid dell'oggetto EncoderParameter su EncoderTransformation.
L'applicazione console seguente crea un oggetto Image da un file JPEG e quindi salva l'immagine in un nuovo file. Durante il processo di salvataggio, l'immagine viene ruotata a 90 gradi. Se la larghezza e l'altezza dell'immagine sono entrambe più di 16, il processo di rotazione e salvataggio dell'immagine causa nessuna perdita di informazioni.
La funzione principale si basa sulla funzione helper GetEncoderClsid, visualizzata in Recupero dell'identificatore di classe per un codificatore.
#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;
}