Manipulace s obrázky ve formátu JPEG

Použití třídy ExifData k čtení a modifikaci EXIF značek JPEG

Téměř všechny digitální fotoaparáty (včetně chytrých telefonů), skenery a další systémy pro manipulaci s obrázky ukládají obrázky s informacemi EXIF (Exchangeable Image File). Fotoaparát zaznamenává do souboru s obrazem informace o nastavení kamery a scéně. EXIF data také zahrnují časy závěrky, datum a čas pořízení fotografie, ohniskovou vzdálenost, kompenzaci expozice, vzor měření a informaci o použití blesku. API Aspose.Imaging umožňuje extrahovat informace EXIF ze zadaného obrázku velmi snadným a jednoduchým způsobem. Vývojáři mohou také zapisovat EXIF data do obrázků nebo upravovat existující informace podle svých potřeb. Aspose.Imaging poskytuje třídu ExifData pro čtení, zápis a modifikaci EXIF dat, zatímco obor názvů Aspose.PSD.Exif.Enums obsahuje relevantní výčty používané v procesu.

Čtení EXIF dat

API Aspose.PSD poskytuje způsoby, jak číst EXIF data ze zadaného obrázku. Níže uvedené kroky ilustrují použití třídy ExifData pro čtení informací EXIF z obrázku.

  • Načtěte obrázek PSD pomocí metody Load.
  • Najděte náhled v JPEG mezi zdroji PSD.
  • Extrahujte instanci třídy ExifData.

Získejte požadované informace a zapište je na konzoli.

String dataDir = Utils.getDataDir(ReadAllEXIFTags.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Extract exif data and print to the console.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
JpegExifData exif = thumbnail.getJpegOptions().getExifData();
if (exif != null) {
for (int j = 0; j < exif.getProperties().length; j++) {
System.out.println(exif.getProperties()[j].getId() + ":" + exif.getProperties()[j].getValue());
}
}
}
}
}

Alternativně mohou vývojáři získat konkrétní informace pomocí následujícího kódu.

String dataDir = Utils.getDataDir(ReadSpecificEXIFTagsInformation.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Extract exif data and print to the console.
JpegExifData exif = ((ThumbnailResource) image.getImageResources()[i]).getJpegOptions().getExifData();
if (exif != null) {
System.out.println("Exif WhiteBalance: " + exif.getWhiteBalance());
System.out.println("Exif PixelXDimension: " + exif.getPixelXDimension());
System.out.println("Exif PixelYDimension: " + exif.getPixelYDimension());
System.out.println("Exif ISOSpeed: " + exif.getISOSpeed());
System.out.println("Exif FocalLength: " + exif.getFocalLength());
}
}
}
}

Zapisování a modifikace EXIF dat

Pomocí API Aspose.PSD mohou vývojáři zapisovat nové informace EXIF a modifikovat existující EXIF data obrázku. Obě procesy (Zapisování a Modifikace) vyžadují načtení obrázku a získání EXIF dat do instance třídy ExifData. Poté můžete přistupovat k vlastnostem zpřístupněným třídou ExifData ke správnému nastavení. Všimněte si, že obrázky určené k manipulaci by měly být obrázky ve formátu JPEG nebo TIFF, které jsou obvykle náhledy PSD. Ukázkový kód pro demonstraci použití je následující:

String dataDir = Utils.getDataDir(WritingAndModifyingEXIFData.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Extract exif data and print to the console.
JpegExifData exif = ((ThumbnailResource) image.getImageResources()[i]).getJpegOptions().getExifData();
if (exif != null) {
// Set LensMake, WhiteBalance, Flash information Save the image
exif.setLensMake("Sony");
exif.setWhiteBalance(ExifWhiteBalance.Auto);
exif.setFlash(ExifFlash.Fired);
}
}
}
image.save(dataDir + "aspose_out.psd");
}

Extrakce náhledů ze zdrojů PSD

Náhledy jsou zmenšené verze obrázků, které slouží k zobrazení významné části obrázku místo celého snímku. Některé obrazové soubory (zejména ty pořízené digitálním fotoaparátem) obsahují vložený náhled obrazu ve souboru. API Aspose.PSD vám umožňuje extrahovat náhledy zdrojů PSD a ukládat je samostatně na disk. Zdroje náhledů obsahují vlastnost ExifData.Thumbnail, která může získat data náhledu. Následující kódová ukázka demonstruje, jak to provést.

String dataDir = Utils.getDataDir(ExtractThumbnailFromPSD.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Extract thumbnail data and store it as a separate image file.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
int[] data = ((ThumbnailResource) image.getImageResources()[i]).getThumbnailArgb32Data();
try (PsdImage extractedThumnailImage = new PsdImage(thumbnail.getWidth(), thumbnail.getHeight())) {
extractedThumnailImage.saveArgb32Pixels(extractedThumnailImage.getBounds(), data);
extractedThumnailImage.save(dataDir + "extracted_thumbnail.jpg", new JpegOptions());
}
}
}
}

Použijte výše diskutovaný přístup ke zpřístupnění náhledu v jiných podporovaných formátech souborů. Pokud chcete exportovat data náhledu do jiných formátů obrázků jako BMP a PNG, použijte jiné možnosti exportu obrázků.

Extrakce náhledů z segmentů JFIF

Je také možné extrahovat náhledy z segmentů ExifData nebo JFIF v zdrojích náhledů PSD. Následující kód ukazuje, jak provést extrakci dat náhledu z segmentu JFIF nebo ExifData:

String dataDir = Utils.getDataDir(ExtractThumbnailFromPSD.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Extract thumbnail data and store it as a separate image file.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
int[] data = ((ThumbnailResource) image.getImageResources()[i]).getThumbnailArgb32Data();
try (PsdImage extractedThumnailImage = new PsdImage(thumbnail.getWidth(), thumbnail.getHeight())) {
extractedThumnailImage.saveArgb32Pixels(extractedThumnailImage.getBounds(), data);
extractedThumnailImage.save(dataDir + "extracted_thumbnail.jpg", new JpegOptions());
}
}
}
}

Použijte výše diskutovaný přístup ke zpracování náhledu v jiných podporovaných formátech souborů. Pokud chcete exportovat data náhledu do jiných formátů obrázků jako BMP a PNG, použijte jiné možnosti exportu obrázků.

Přidání náhledu do segmentu JFIF

Následující kódová ukázka ukazuje, jak použít vlastnost JFIF.Thumbnail k přidání náhledového obrázku do segmentu JFIF načteného obrázku PSD.

String dataDir = Utils.getDataDir(AddThumbnailToJFIFSegment.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Adjust thumbnail data.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
JpegExifData exifData = new JpegExifData();
PsdImage thumbnailImage = new PsdImage(100, 100);
try {
// Fill thumbnail data.
int[] pixels = new int[thumbnailImage.getWidth() * thumbnailImage.getHeight()];
for (int j = 0; j < pixels.length; j++) {
pixels[j] = j;
}
// Assign thumbnail data.
thumbnailImage.saveArgb32Pixels(thumbnailImage.getBounds(), pixels);
exifData.setThumbnail(thumbnailImage);
thumbnail.getJpegOptions().setExifData(exifData);
} catch (Exception e) {
thumbnailImage.dispose();
}
}
}
image.save();
}

Náhledové obrázky s jinými segmentovými daty nesmějí obsahovat více než 65 545 bajtů kvůli specifikacím formátu JPEG. V případech, kdy jsou velké obrázky určeny k použití jako náhled, může vzniknout výjimka.

Přidání náhledu do segmentu EXIF

Název následujícího kódu ukazuje, jak použít vlastnost ExifData.Thumbnail k přidání náhledového obrázku do segmentu EXIF načteného obrázku PSD.

String dataDir = Utils.getDataDir(AddThumbnailToEXIFSegment.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Adjust thumbnail data.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
JpegExifData exifData = new JpegExifData();
PsdImage thumbnailImage = new PsdImage(100, 100);
try {
// Fill thumbnail data.
int[] pixels = new int[thumbnailImage.getWidth() * thumbnailImage.getHeight()];
for (int j = 0; j < pixels.length; j++) {
pixels[j] = j;
}
// Assign thumbnail data.
thumbnailImage.saveArgb32Pixels(thumbnailImage.getBounds(), pixels);
exifData.setThumbnail(thumbnailImage);
thumbnail.getJpegOptions().setExifData(exifData);
} catch (Exception e) {
thumbnailImage.dispose();
}
}
}
image.save();
}

V tomto případě API Aspose.PSD nemůže odhadnout velikost náhledového obrázku, ale může zkontrolovat velikost celého segmentu dat EXIF. Tato velikost nemůže být větší než 65 535 bajtů.

Použití třídy JpegExifData k čtení a modifikaci EXIF značek JPEG

API Aspose.PSD poskytuje třídu JpegExifData, která je exkluzivní pro formáty obrázků ve formátu JPEG k získání a aktualizaci informací EXIF. Tento článek demonstruje použití třídy JpegExifData k dosažení stejného cíle. Třída Aspose.PSD.Exif.JpegExifData slouží jako kontejner EXIF dat pro obrázky ve formátu JPEG a poskytuje způsob, jak získat standardní EXIF značky JPEG, jak je uvedeno níže:

String dataDir = Utils.getDataDir(AddThumbnailToEXIFSegment.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Adjust thumbnail data.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
JpegExifData exifData = new JpegExifData();
PsdImage thumbnailImage = new PsdImage(100, 100);
try {
// Fill thumbnail data.
int[] pixels = new int[thumbnailImage.getWidth() * thumbnailImage.getHeight()];
for (int j = 0; j < pixels.length; j++) {
pixels[j] = j;
}
// Assign thumbnail data.
thumbnailImage.saveArgb32Pixels(thumbnailImage.getBounds(), pixels);
exifData.setThumbnail(thumbnailImage);
thumbnail.getJpegOptions().setExifData(exifData);
} catch (Exception e) {
thumbnailImage.dispose();
}
}
}
image.save();
}

Kompletní seznam EXIF značek

Výše uvedený kód čte několik EXIF značek pomocí vlastností nabízených třídou Aspose.PSD.Exif.JpegExifData. Kompletní seznam těchto vlastností je k dispozici zde. Následující kód přečte všechny EXIF značky pomocí třídy System.Reflection.PropertyInfo.

Automatická korekce orientace obrázků ve formátu JPEG

Fotografie mohou být pořízeny fotoaparátem otočeným o 90°, 180°, 270° nebo žádným směrem (normální orientace). Většina digitálních fotoaparátů ukládá informace o orientaci spolu s daty obrázku jako EXIF značky obrázků ve formátu JPEG. Tyto informace lze použít k automatickému otáčení obrázků k opravě orientace. API Aspose.PSD poskytuje metodu AutoRotate pro třídu JpegImage k automatické korekci orientace obrázků ve formátu JPEG. Zde je příklad, jak můžete použít metodu AutoRotate s API Aspose.PSD pro Java.

String dataDir = Utils.getDataDir(AutoCorrectOrientationOfJPEGImages.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "1280px-Zebras_Serengeti.psd")) {
// Iterate over resources.
for (int i = 0; i < image.getImageResources().length; i++) {
// Find thumbnail resource. Typically they are in the Jpeg file format.
if (image.getImageResources()[i] instanceof ThumbnailResource || image.getImageResources()[i] instanceof Thumbnail4Resource) {
// Adjust thumbnail data.
ThumbnailResource thumbnail = (ThumbnailResource) image.getImageResources()[i];
JpegExifData exifData = thumbnail.getJpegOptions().getExifData();
if (exifData != null && exifData.getThumbnail() != null) {
// If there is thumbnail stored then auto-rotate it.
JpegImage jpegImage = (JpegImage) exifData.getThumbnail();
if (jpegImage != null) {
jpegImage.autoRotate();
}
}
}
}
// Save image.
image.save();
}

Podpora pro JPEG-LS s modely barev CMYK a YCCK

API Aspose.PSD pro jazyk Java poskytuje podporu pro modely barev CMYK a YCCK s formátem JPEG-LS. Následující kódová ukázka ukazuje, jak tuto podporu pro JPEG-LS použít.

String dataDir = Utils.getDataDir(SupportForJPEGLSWithCMYK.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "PsdImage.psd")) {
JpegOptions options = new JpegOptions();
//Just replace one line given below in examples to use YCCK instead of CMYK
//options.ColorType = JpegCompressionColorMode.Cmyk;
options.setColorType(JpegCompressionColorMode.Cmyk);
options.setCompressionType(JpegCompressionMode.JpegLs);
// The default profiles will be used.
options.setRgbColorProfile(null);
options.setCmykColorProfile(null);
image.save(dataDir + "output.jpg", options);
}
try (PsdImage image1 = (PsdImage) Image.load(dataDir + "PsdImage.psd")) {
JpegOptions options1 = new JpegOptions();
//Just replace one line given below in examples to use YCCK instead of CMYK
//options.ColorType = JpegCompressionColorMode.Cmyk;
options1.setColorType(JpegCompressionColorMode.Cmyk);
options1.setCompressionType(JpegCompressionMode.Lossless);
// The default profiles will be used.
options1.setRgbColorProfile(null);
options1.setCmykColorProfile(null);
image1.save(dataDir + "output2.jpg", options1);
}

Podpora pro JPEG-LS s 2-7 bity na vzorek

API Aspose.PSD pro jazyk Java poskytuje podporu pro JPEG-LS obrázky s 2-7 bity na vzorek. Následující kódová ukázka ukazuje, jak tuto podporu pro JPEG-LS použít.

String dataDir = Utils.getDataDir(SupportFor2And7BitsJPEG.class) + "ModifyingAndConvertingImages/";
try (PsdImage image = (PsdImage) Image.load(dataDir + "PsdImage.psd")) {
JpegOptions options = new JpegOptions();
// Set 2 bits per sample to see the difference in size and quality
byte bpp = 2;
//Just replace one line given below in examples to use YCCK instead of CMYK
//options.ColorType = JpegCompressionColorMode.Cmyk;
options.setColorType(JpegCompressionColorMode.Cmyk);
options.setCompressionType(JpegCompressionMode.JpegLs);
options.setBitsPerChannel(bpp);
// The default profiles will be used.
options.setRgbColorProfile(null);
options.setCmykColorProfile(null);
image.save(dataDir + "2_7BitsJPEG_output.jpg", options);
}

Nastavení typu barvy a typu komprese pro obrázky ve formátu JPEG

API Aspose.PSD pro jazyk Java poskytuje podporu pro typ barvy a typ komprese a nastavuje je jako stupně šedi a progresivní pro obrázky ve formátu JPEG. Následující kódová ukázka ukazuje, jak tuto podporu použít.