Convertendo Imagens

Convertendo Imagens para Preto e Branco e Escala de Cinza

Às vezes, pode ser necessário converter imagens coloridas para preto e branco ou escala de cinza para fins de impressão ou arquivamento. Este artigo demonstra o uso da API Aspose.PSD para Java para alcançar isso usando dois métodos conforme indicado abaixo.

  • Binarização
  • Escalonamento de Cinza

Binarização

Para entender o conceito de Binarização, é importante definir uma Imagem Binária; ou seja, uma imagem digital que pode ter apenas dois valores possíveis para cada pixel. Normalmente, as duas cores usadas para uma imagem binária são preto e branco, embora qualquer duas cores possam ser usadas. Binarização é o processo de converter uma imagem em bi-nível, ou seja, cada pixel é armazenado como um único bit (0 ou 1), onde 0 denota a ausência de cor e 1 significa presença de cor. A API Aspose.PSD para Java atualmente suporta dois métodos de binarização.

Binarização com Limiar Fixo

O trecho de código a seguir mostra como aplicar a binarização com limiar fixo a uma imagem.

String dataDir = Utils.getDataDir(BinarizationWithFixedThreshold.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "BinarizationWithFixedThreshold_out.jpg";
try (Image image = Image.load(sourceFile);
RasterCachedImage rasterCachedImage = (RasterCachedImage) image) {
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Binarize image with predefined fixed threshold and Save the resultant image
rasterCachedImage.binarizeFixed((byte) 100);
rasterCachedImage.save(destName, new JpegOptions());
}

Binarização com Limiar de Otsu

O trecho de código a seguir mostra como aplicar a binarização com limiar de Otsu a uma imagem.

String dataDir = Utils.getDataDir(BinarizationWithOtsuThreshold.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "BinarizationWithOtsuThreshold_out.jpg";
try (Image image = Image.load(sourceFile);
// Cast the image to RasterCachedImage and Check if image is cached
RasterCachedImage rasterCachedImage = (RasterCachedImage) image) {
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Binarize image with Otsu Thresholding and Save the resultant image
rasterCachedImage.binarizeOtsu();
rasterCachedImage.save(destName, new JpegOptions());
}

Escala de Cinza

Escalonamento de cinza é o processo de converter uma imagem de tons contínuos em uma imagem com tons de cinza descontínuos. O trecho de código a seguir mostra como usar o escalonamento de cinza.

String dataDir = Utils.getDataDir(GrayScaling.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "Grayscaling_out.jpg";
try (Image image = Image.load(sourceFile)) {
// Cast the image to RasterCachedImage and Check if image is cached
RasterCachedImage rasterCachedImage = (RasterCachedImage) image;
if (!rasterCachedImage.isCached()) {
// Cache image if not already cached
rasterCachedImage.cacheData();
}
// Transform image to its grayscale representation and Save the resultant image
rasterCachedImage.grayscale();
rasterCachedImage.save(destName, new JpegOptions());
}

Converter Camadas de Imagem GIF para Imagem TIFF

Às vezes é necessário extrair e converter camadas de uma imagem PSD em outro formato de imagem raster para atender a uma necessidade do aplicativo. A API Aspose.PSD suporta a funcionalidade de extrair e converter camadas de uma imagem PSD em outro formato de imagem raster. Primeiramente, criaremos uma instância de imagem e carregaremos a imagem PSD do disco local, então iteraremos cada camada na propriedade Layer. Em seguida, converteremos o bloco em imagem TIFF. O trecho de código a seguir mostra como converter camadas de imagem PSD em imagens TIFF.

String dataDir = Utils.getDataDir(GIFImageLayersToTIFF.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
// Load a PSD image and Convert the image's layers to Tiff images.
try (PsdImage image = (PsdImage) Image.load(sourceFile)) {
// Iterate through array of PSD layers
for (int i = 0; i < image.getLayers().length; i++) {
// Get PSD layer.
Layer layer = image.getLayers()[i];
// Create an instance of TIFF Option class and Save the PSD layer as TIFF image
TiffOptions objTiff = new TiffOptions(TiffExpectedFormat.TiffDeflateRgb);
layer.save("output" + i + "_out.tiff", objTiff);
}
}

Convertendo PSD CMYK para TIFF CMYK

Usando Aspose.PSD para Java, os desenvolvedores podem converter arquivos PSD CMYK para o formato TIFF CMYK. Este artigo mostra como exportar / converter arquivos PSD CMYK para o formato de imagem TIFF CMYK com o Aspose.PSD. Usando Aspose.PSD para Java, você pode carregar imagens PSD e então pode definir várias propriedades usando a classe TiffOptions e salvar ou exportar a imagem. O trecho de código a seguir mostra como alcançar essa funcionalidade.

String dataDir = Utils.getDataDir(CMYKPSDtoCMYKTiff.class) + "Conversion/";
String sourceFile = dataDir + "sample.psd";
String destName = dataDir + "output.tiff";
try (Image image = Image.load(sourceFile)) {
image.save(destName, new TiffOptions(TiffExpectedFormat.TiffLzwCmyk));
}

Exportando Imagens

Junto com um extenso conjunto de rotinas de processamento de imagem, o Aspose.PSD fornece classes especializadas para converter formatos de arquivo PSD para outros formatos. Usando esta biblioteca, a conversão de imagens PSD é muito simples e intuitiva. Abaixo estão algumas classes especializadas para este fim no espaço de nome ImageOptions.

  • BmpOptions
  • GifOptions
  • JpegOptions
  • Jpeg2000Options
  • TiffOptions
  • PngOptions

É fácil exportar imagens PSD com a API Aspose.PSD para Java. Tudo o que você precisa é de um objeto da classe apropriada do espaço de nome ImageOptions. Usando essas classes, você pode facilmente exportar qualquer imagem criada, editada ou simplesmente carregada com o Aspose.PSD para Java para qualquer formato suportado.

Combinando Imagens

Este exemplo usa a classe Graphics e mostra como combinar duas ou mais imagens em uma única imagem completa. Para demonstrar a operação, o exemplo cria uma nova PsdImage e desenha imagens na superfície do canvas usando o método DrawImage exposto pela classe Graphics. Usando a classe Graphics, duas ou mais imagens podem ser combinadas de tal forma que a imagem resultante parecerá uma imagem completa, sem espaço entre as partes da imagem e sem páginas. O tamanho do canvas deve ser igual ao tamanho da imagem resultante. A seguir está a demonstração de código que mostra como usar o método DrawImage da classe Graphics para combinar imagens em uma única imagem.

String dataDir = Utils.getDataDir(CombiningImages.class) + "DrawingAndFormattingImages/";
// Create an instance of PsdOptions and set its various properties
PsdOptions imageOptions = new PsdOptions();
// Create an instance of FileCreateSource and assign it to Source property
imageOptions.setSource(new FileCreateSource(dataDir + "Two_images_result_out.psd", false));
try (Image image = Image.create(imageOptions, 600, 600)) {
// Create and initialize an instance of Graphics, Clear the image surface with white color and Draw Image
Graphics graphics = new Graphics(image);
graphics.clear(Color.getWhite());
graphics.drawImage(Image.load(dataDir + "example1.psd"), 0, 0, 300, 600);
graphics.drawImage(Image.load(dataDir + "example2.psd"), 300, 0, 300, 600);
image.save();
}

Expandir e Cortar Imagens

A API Aspose.PSD permite que você expanda ou corte uma imagem durante o processo de conversão de imagem. O desenvolvedor precisa criar um retângulo com as coordenadas X e Y e especificar a largura e altura da caixa do retângulo. As coordenadas X, Y e Largura, Altura do retângulo irão representar a expansão ou o corte da imagem carregada. Se for necessário expandir ou cortar a imagem durante a conversão de imagem, siga as etapas abaixo:

  1. Crie uma instância da classe RasterImage e carregue a imagem existente.
  2. Crie uma instância da classe ImageOption.
  3. Crie uma instância da classe Rectangle e inicialize as coordenadas X, Y e Largura, Altura do retângulo.
  4. Chame o método Save da classe RasterImage enquanto passa o nome do arquivo de saída, as opções de imagem e o objeto retângulo como parâmetros.
String dataDir = Utils.getDataDir(ExpandAndCropImages.class) + "DrawingAndFormattingImages/";
String sourceFile = dataDir + "example1.psd";
String destName = dataDir + "jpeg_out.jpg";
try (RasterImage rasterImage = (RasterImage) Image.load(sourceFile)) {
rasterImage.cacheData();
// Create an instance of Rectangle class and define X,Y and Width, height of the rectangle, and Save output image
Rectangle destRect = new Rectangle(-200, -200, 300, 300);
rasterImage.save(destName, new JpegOptions(), destRect);
}

Ler e Escrever Dados XMP nas Imagens

XMP (Plataforma de Metadados Extensíveis) é um padrão ISO. O XMP padroniza um modelo de dados, um formato de serialização e propriedades centrais para definição e processamento de metadados extensíveis. Também fornece diretrizes para embutir informações XMP em imagens populares, como JPEG, sem comprometer a legibilidade por aplicativos que não suportam XMP. Usando a API Aspose.PSD para Java, os desenvolvedores podem ler ou escrever metadados XMP em imagens. Este artigo demonstra como os metadados XMP podem ser lidos de uma imagem e como os metadados XMP podem ser escritos nas imagens.

Criar Metadados XMP, Escrevê-los e Ler de um Arquivo

Com a ajuda do espaço de nomes XMP, o desenvolvedor pode criar um objeto de metadados XMP e escrevê-lo em uma imagem. O trecho de código a seguir mostra como usar os pacotes XmpHeaderPi, XmpTrailerPi, XmpMeta, XmpPacketWrapper, PhotoshopPackage e DublinCorePackage contidos no espaço de nomes XMP.

String dataDir = Utils.getDataDir(CreateXMPMetadata.class) + "DrawingAndFormattingImages/";
// Specify the size of image by defining a Rectangle
Rectangle rect = new Rectangle(0, 0, 100, 200);
// create the brand new image just for sample purposes
try (PsdImage image = new PsdImage(rect.getWidth(), rect.getHeight())) {
// create an instance of XMP-Header
XmpHeaderPi xmpHeader = new XmpHeaderPi();
xmpHeader.setGuid(dataDir);
// create an instance of Xmp-TrailerPi
XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
// create an instance of XMPmeta class to set different attributes
XmpMeta xmpMeta = new XmpMeta();
xmpMeta.addAttribute("Author", "Mr Smith");
xmpMeta.addAttribute("Description", "The fake metadata value");
// create an instance of XmpPacketWrapper that contains all metadata
XmpPacketWrapper xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
// create an instacne of Photoshop package and set photoshop attributes
PhotoshopPackage photoshopPackage = new PhotoshopPackage();
photoshopPackage.setCity("London");
photoshopPackage.setCountry("England");
photoshopPackage.setColorMode(ColorMode.Rgb);
// add photoshop package into XMP metadata
xmpData.addPackage(photoshopPackage);
// create an instacne of DublinCore package and set dublinCore attributes
DublinCorePackage dublinCorePackage = new DublinCorePackage();
dublinCorePackage.setAuthor("Charles Bukowski");
dublinCorePackage.setTitle("Confessions of a Man Insane Enough to Live With the Beasts");
dublinCorePackage.addValue("dc:movie", "Barfly");
// add dublinCore Package into XMP metadata
xmpData.addPackage(dublinCorePackage);
MemoryStream ms = new MemoryStream();
// update XMP metadata into image
image.setXmpData(xmpData);
// Save image on the disk or in memory stream
image.save(dataDir + "create_XMP_Metadata.psd");
}

Exportar Imagens em Ambiente de Múltiplas Threads

O Aspose.PSD para Java agora suporta a conversão de imagens em um ambiente de várias threads. O Aspose.PSD para Java garante o desempenho otimizado das operações durante a execução de código em um ambiente de várias threads. Todas as classes de opção de imagem (por exemplo, BmpOptions, TiffOptions, JpegOptions, etc.) no Aspose.PSD para Java implementam a interface IDisposable. Portanto, é obrigatório que o desenvolvedor libere adequadamente o objeto da classe de opções de imagem no caso de a propriedade Source ser definida. O trecho de código a seguir demonstra essa funcionalidade.

String dataDir = Utils.getDataDir(ExportImagesinMultiThreadEnv.class) + "Conversion/";
String imageDataPath = dataDir + "sample.psd";
try {
FileInputStream fileStream = new FileInputStream(imageDataPath);
PsdOptions psdOptions = new PsdOptions();
// Set the source property of the imaging option class object.
psdOptions.setSource(new StreamSource(fileStream));
// Following is the sample processing on the image.
RasterImage image = (RasterImage) Image.create(psdOptions, 10, 10);
Color[] pixels = new Color[4];
for (int i = 0; i < 4; ++i) {
pixels[i] = Color.fromArgb(40, 30, 20, 10);
}
image.savePixels(new Rectangle(0, 0, 2, 2), pixels);
image.save();
} finally {
// Delete the output file.
File f = new File(imageDataPath);
if (f.exists()) {
f.delete();
}
}

O Aspose.PSD agora suporta a propriedade SyncRoot ao trabalhar em um ambiente de várias threads. O desenvolvedor pode usar essa propriedade para sincronizar o acesso ao fluxo de origem. O trecho de código a seguir demonstra como a propriedade SyncRoot pode ser usada.

String dataDir = Utils.getDataDir(SyncRoot.class) + "Conversion/";
// Create an instance of Stream container class and assign memory stream object.
StreamContainer streamContainer = new StreamContainer(new java.io.ByteArrayInputStream(new byte[0]));
try {
// check if the access to the stream source is synchronized.
synchronized (streamContainer.getSyncRoot()) {
// do work
// now access to streamContainer is synchronized
}
} finally {
streamContainer.dispose();
}