Конвертация изображений
Преобразование изображений в черно-белое и градации серого цвета
Иногда вам может потребоваться преобразовать цветные изображения в черно-белые или в оттенки серого для печати или архивирования. В этой статье демонстрируется использование Aspose.PSD для Java API для достижения этого с помощью двух методов, описанных ниже.
- Двоичное изображение (Binarization)
- Преобразование в градации серого (Grayscaling)
Двоичное изображение (Binarization)
Для понимания концепции двоичного изображения важно определить, что такое двоичное изображение; это цифровое изображение, у которого каждый пиксель может иметь только два возможных значения. Обычно для двоичного изображения используются два цвета: черный и белый, хотя можно использовать любые два цвета. Двоичное преобразование - это процесс преобразования изображения в двоичное, что означает, что каждый пиксель хранится как один бит (0 или 1), где 0 обозначает отсутствие цвета, а 1 означает наличие цвета. Aspose.PSD для Java API в настоящее время поддерживает два метода двоичного изображения.
Двоичное преобразование с фиксированным порогом (Binarization with Fixed Threshold)
Следующий фрагмент кода показывает, как применить двоичное преобразование с фиксированным порогом к изображению.
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()); | |
} |
Двоичное преобразование с порогом Оцу (Binarization with Otsu Threshold)
Следующий фрагмент кода показывает, как применить двоичное преобразование с порогом Оцу к изображению.
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()); | |
} |
Преобразование в градации серого (Grayscaling)
Градации серого - это процесс преобразования непрерывно-тонового изображения в изображение с разрывными оттенками серого. Следующий фрагмент кода показывает, как использовать градации серого.
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()); | |
} |
Преобразование слоев изображений GIF в изображения TIFF
Иногда необходимо извлечь и преобразовать слои изображения PSD в другой растровый формат изображения для удовлетворения потребностей приложения. Aspose.PSD API поддерживает функцию извлечения и преобразования слоев изображения PSD в другой растровый формат изображения. Сначала мы создадим экземпляр изображения и загрузим изображение PSD с локального диска, затем мы переберем каждый слой в свойстве Layer. Затем мы преобразуем блок в изображение TIFF. Следующий фрагмент кода показывает, как преобразовать слои изображения PSD в изображения 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); | |
} | |
} |
Преобразование CMYK PSD в CMYK TIFF
С помощью Aspose.PSD для Java разработчики могут преобразовать файл CMYK PSD в формат CMYK Tiff. В этой статье показано, как экспортировать / конвертировать файл CMYK PSD в формат tiff CMYK с помощью Aspose.PSD. Используя Aspose.PSD для Java, вы можете загружать изображения PSD, задавать различные свойства с помощью класса TiffOptions и сохранять или экспортировать изображение. Следующий фрагмент кода показывает, как реализовать эту функцию.
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)); | |
} |
Экспорт изображений
Вместе с обширным набором процедур обработки изображений, Aspose.PSD предоставляет специализированные классы для преобразования форматов файлов PSD в другие форматы. Используя эту библиотеку, конвертация изображений PSD становится очень простой и интуитивной. Ниже приведены некоторые специализированные классы для этой цели в пространстве имен ImageOptions.
- BmpOptions
- GifOptions
- JpegOptions
- Jpeg2000Options
- TiffOptions
- PngOptions
Экспортировать изображения PSD с помощью Aspose.PSD для Java API легко. Вам просто нужен объект соответствующего класса из пространства имен ImageOptions. Используя эти классы, вы можете легко экспортировать любое изображение, созданное, отредактированное или просто загруженное с помощью Aspose.PSD для Java, в любой поддерживаемый формат.
Комбинирование изображений
Этот пример использует класс Graphics и показывает, как объединить два или более изображений в одно полное изображение. Для демонстрации операции пример создает новое изображение PsdImage и рисует изображения на поверхности холста, используя метод Draw Image, предоставленный классом Graphics. С помощью класса Graphics можно объединить два или более изображения таким образом, что полученное изображение будет выглядеть как целое изображение без промежутков между частями изображения и без страниц. Размер холста должен быть равен размеру полученного изображения. Вот код, который показывает, как использовать метод Draw Image класса Graphics для объединения изображений в одно изображение.
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(); | |
} |
Расширение и обрезка изображений
API Aspose.PSD позволяет вам расширить или обрезать изображение во время процесса преобразования изображения. Разработчику необходимо создать прямоугольник с координатами X и Y, а также указать ширину и высоту прямоугольного блока. X, Y и ширина, высота прямоугольника будут показывать расширение или обрезку загруженного изображения. Если требуется расширить или обрезать изображение во время преобразования изображения, выполните следующие шаги:
- Создайте экземпляр класса RasterImage и загрузите существующее изображение.
- Создайте экземпляр класса ImageOption.
- Создайте экземпляр класса Rectangle и инициализируйте X, Y и ширину, высоту прямоугольника.
- Вызовите метод Save класса RasterImage, передав имя файла вывода, параметры изображения и объект прямоугольника в качестве параметров.
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); | |
} |
Чтение и запись метаданных XMP в изображения
XMP (Extensible Metadata Platform) является стандартом ISO. XMP стандартизирует модель данных, формат сериализации и основные свойства для определения и обработки расширенных метаданных. Он также предоставляет рекомендации по встраиванию информации XMP в популярные изображения, такие как JPEG, без нарушения их читаемости приложениями, не поддерживающими XMP. С помощью Aspose.PSD для Java API разработчики могут читать или записывать метаданные XMP в изображения. Эта статья демонстрирует, как метаданные XMP могут быть прочитаны из изображения и записаны в изображения.
Создание метаданных XMP, запись и чтение из файла
С помощью пространства имен XMP разработчик может создать объект метаданных XMP и записать его в изображение. Следующий фрагмент кода показывает, как использовать пакеты XmpHeaderPi, XmpTrailerPi, XmpMeta, XmpPacketWrapper, PhotoshopPackage и DublinCorePackage, содержащиеся в пространстве имен 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"); | |
} |
Экспорт изображений в многопоточной среде
Aspose.PSD для Java теперь поддерживает преобразование изображений в многопоточной среде. Aspose.PSD для Java гарантирует оптимизированную производительность операций во время выполнения кода в многопоточной среде. Все классы параметров изображения (например, BmpOptions, TiffOptions, JpegOptions и т. д.) в Aspose.PSD для Java реализуют интерфейс IDisposable. Поэтому необходимо правильно уничтожить объект класса параметров изображения в случае, если установлено свойство Source. Следующий фрагмент кода демонстрирует указанную функциональность.
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(); | |
} | |
} |
Теперь Aspose.PSD поддерживает свойство SyncRoot при работе в многопоточной среде. Разработчик может использовать это свойство для синхронизации доступа к источнику данных. Следующий фрагмент кода демонстрирует, как можно использовать свойство SyncRoot.
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(); | |
} |