Manipulación de imágenes JPEG
Usar la clase ExifData para leer y modificar etiquetas EXIF JPEG
Casi todas las cámaras digitales (incluyendo smartphones), escáneres y otros sistemas que manejan imágenes guardan imágenes con información EXIF (Exchangeable Image File). La cámara registra en el archivo de imagen la configuración de la cámara y la información de la escena. Los datos EXIF también incluyen la velocidad de obturación, la fecha y hora en que se tomó una foto, la longitud focal, la compensación de exposición, el patrón de medición y si se usó un flash. Las APIs de Aspose.Imaging han hecho posible extraer la información EXIF de una imagen dada de una manera fácil y sencilla. Los desarrolladores también pueden escribir datos EXIF en las imágenes o modificar la información existente según sea necesario. Aspose.Imaging ha proporcionado la clase ExifData para leer, escribir y modificar los datos EXIF, donde Aspose.PSD.Exif.Enums namespace contiene las enumeraciones relevantes utilizadas en el proceso.
Lectura de datos EXIF
Las APIs de Aspose.PSD proporcionan medios para leer datos EXIF de una imagen dada. Los pasos proporcionados a continuación ilustran el uso de la clase ExifData para leer la información EXIF de una imagen.
- Cargar la imagen PSD usando el método de fábrica Load.
- Encontrar la miniatura JPEG entre los recursos PSD.
- Extraer una instancia de la clase ExifData.
Obtener la información requerida y escribirla en la consola.
Alternativamente, los desarrolladores también pueden obtener la información específica utilizando el siguiente fragmento de código.
Escritura y Modificación de Datos EXIF
Utilizando las APIs de Aspose.PSD, los desarrolladores pueden escribir nueva información EXIF y modificar datos EXIF existentes de una imagen. Ambos procesos (Escritura y Modificación) requieren cargar una imagen y obtener los datos EXIF en una instancia de la clase ExifData. Luego se puede acceder a las propiedades expuestas por la clase ExifData para configurarlas según sea necesario. Tenga en cuenta que las imágenes para manipulación deben ser imágenes JPEG o TIFF que generalmente son miniaturas PSD. Un código de ejemplo para demostrar el uso es el siguiente:
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"); | |
} |
Extracción de miniaturas de los recursos PSD
Las miniaturas son versiones de menor tamaño de imágenes, usadas para mostrar una parte significativa de la imagen en lugar del cuadro completo. Algunos archivos de imagen (especialmente los tomados con una cámara digital) tienen una imagen en miniatura incrustada en el archivo. La API de Aspose.PSD le permite extraer miniaturas de los recursos PSD y almacenarlas por separado en disco. Los recursos de miniaturas contienen la propiedad ExifData.Thumbnail que puede recuperar los datos de miniatura. El fragmento de código proporcionado a continuación demuestra cómo usarlo.
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()); | |
} | |
} | |
} | |
} |
Utilice el enfoque discutido anteriormente para almacenar la miniatura en otros formatos de archivo admitidos. Si desea exportar datos de miniatura a otros formatos de imagen como BMP y PNG, utilice otras opciones de exportación de imagen.
Extracción de miniaturas de segmentos JFIF
También es posible extraer miniaturas de los segmentos ExifData o JFIF de los recursos de miniaturas PSD. El siguiente código muestra cómo realizar la extracción de datos de miniatura de los segmentos JFIF o 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()); | |
} | |
} | |
} | |
} |
Utilice el enfoque discutido anteriormente para almacenar la miniatura en otros formatos de archivo admitidos. Si desea exportar datos de miniatura a otros formatos de imagen como BMP y PNG, utilice otras opciones de exportación de imagen.
Agregar miniatura al segmento JFIF
El fragmento de código a continuación muestra cómo usar la propiedad JFIF.Thumbnail para agregar una imagen en miniatura al segmento JFIF de una imagen PSD cargada.
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(); | |
} |
Las imágenes en miniatura con otros datos de segmento no pueden ocupar más de 65,545 bytes debido a las especificaciones del formato JPEG. En casos donde se deben establecer imágenes grandes como miniatura, puede surgir una excepción.
Agregar miniatura al segmento EXIF
El fragmento de código a continuación muestra cómo usar la propiedad ExifData.Thumbnail para agregar una imagen en miniatura al segmento EXIF de una imagen PSD cargada.
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(); | |
} |
En este caso, la API de Aspose.PSD no puede estimar el tamaño de la imagen en miniatura, pero puede verificar el tamaño de todo el segmento de datos EXIF. Esto no puede ser mayor de 65,535 bytes.
Usar la clase JpegExifData para leer y modificar etiquetas EXIF JPEG
Las APIs de Aspose.PSD proporcionan la clase JpegExifData que es exclusiva para los formatos de imagen JPEG para recuperar y actualizar información EXIF. Este artículo demuestra el uso de la clase JpegExifData para lograr lo mismo. La clase Aspose.PSD.Exif.JpegExifData sirve como contenedor de datos EXIF para imágenes JPEG, y ofrece medios para recuperar etiquetas EXIF estándar de JPEG como se muestra a continuación:
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(); | |
} |
Lista completa de etiquetas EXIF
El fragmento de código anterior lee algunas etiquetas EXIF utilizando las propiedades ofrecidas por la clase Aspose.PSD.Exif.JpegExifData. La lista completa de estas propiedades está disponible aquí. El siguiente código leerá todas las etiquetas EXIF utilizando la clase System.Reflection.PropertyInfo.
String dataDir = Utils.getDataDir(ReadAllEXIFTagList.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]; | |
JpegExifData exifData = thumbnail.getJpegOptions().getExifData(); | |
if (exifData != null) { | |
for (int j = 0; j < exifData.getProperties().length; j++) { | |
System.out.println(exifData.getProperties()[j].getId() + ":" + exifData.getProperties()[j].getValue()); | |
} | |
} | |
} | |
} | |
} |
Corrección automática de la orientación de las imágenes JPEG
Las fotos pueden tomarse con una cámara girada a 90°, 180°, 270° o ninguna (orientación normal). La mayoría de las cámaras digitales almacenan la información de orientación junto con los datos de imagen como etiquetas EXIF de las imágenes JPEG. Esta información se puede utilizar para realizar la rotación automática en las imágenes para corregir la orientación. Las APIs de Aspose.PSD proporcionan el método AutoRotate para la clase JpegImage para corregir automáticamente la orientación de las imágenes JPEG. Así es como se puede usar el método AutoRotate con Aspose.PSD para la API de 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(); | |
} |
Soporte para JPEG-LS con CMYK y YCCK
Aspose.PSD para la API de Java proporciona soporte para los modelos de color CMYK y YCCK con JPEG-LS. El fragmento de código a continuación demuestra cómo usar ese soporte para JPEG-LS.
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); | |
} |
Soporte para imágenes JPEG-LS de 2-7 bits por muestra
Aspose.PSD para la API de Java proporciona soporte para imágenes JPEG-LS de 2 a 7 bits por muestra. El fragmento de código a continuación demuestra cómo usar ese soporte para JPEG-LS.
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); | |
} |
Establecer ColorType y CompressionType para imágenes JPEG
Aspose.PSD para la API de Java proporciona soporte para Tipo de Color y Tipo de Compresión y establecerlos como escala de grises y progresivo para imágenes JPEG. El fragmento de código a continuación demuestra cómo usar ese soporte.