تحويل الصور
تحويل الصور إلى أبيض وأسود وتدرج الرمادي
أحيانًا قد تحتاج إلى تحويل الصور الملونة إلى أبيض وأسود أو تدرج الرمادي لأغراض الطباعة أو الأرشفة. يظهر هذا المقال استخدام Aspose.PSD لواجهة برمجة التطبيقات في جافا لتحقيق ذلك باستخدام طريقتين كما هو مذكور أدناه.
- التثنية
- تدرج الرمادي
التثنية
من أجل فهم مفهوم التثنية، من المهم تعريف الصورة الثنائية؛ وهي صورة رقمية يمكن أن تحتوي على قيمتين ممكنتين فقط لكل بكسل. عادةً، اللونين المستخدمين للصورة الثنائية هما الأسود والأبيض على الرغم من أنه يمكن استخدام أي لونين. التثنية هي عملية تحويل الصورة إلى ثنائية المستوى بحيث يتم تخزين كل بكسل على أنه بت واحد (0 أو 1) حيث يشير 0 إلى عدم وجود لون ويعني 1 وجود لون. تدعم واجهة Aspose.PSD لجافا حاليًا طريقتين للتثنية.
التثنية بحدود ثابتة
يظهر مقتطف الكود التالي كيف يمكن استخدام التثنية بحدود ثابتة على صورة.
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()); | |
} |
التثنية بحد الـ Otsu
يظهر مقتطف الكود التالي كيف يمكن تطبيق التثنية بحد الـ Otsu على صورة.
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()); | |
} |
تدرج الرمادي
تدرج الرمادي هو عملية تحويل صورة مستمرة الدرجات إلى صورة مع درجات رمادية متقطعة. يظهر مقتطف الكود التالي كيفية استخدام تدرج الرمادي.
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 إمكانية استخراج وتحويل طبقات صورة PSD إلى تنسيق صورة نقطية آخرى. أولاً، سنقوم بإنشاء نموذج للصورة وتحميل صورة PSD من القرص المحلي، ثم سنكرر كل طبقة في خاصية الطبقة. ثم سنقوم بتحويل الكتلة إلى صورة 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); | |
} | |
} |
تحويل PSD CMYK إلى TIFF CMYK
باستخدام Aspose.PSD لجافا، يمكن للمطورين تحويل ملف PSD CMYK إلى تنسيق TIFF CMYK. يوضح هذا المقال كيفية تصدير/تحويل ملف PSD CMYK إلى تنسيق TIFF CMYK باستخدام Aspose.PSD. باستخدام Aspose.PSD لجافا، يمكنك تحميل صور 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 لواجهة برمجة التطبيقات في جافا. كل ما تحتاج إليه هو كائن من الفئة المناسبة من فئة ImageOptions. باستخدام هذه الفئات، يمكنك بسهولة تصدير أي صورة تم إنشاؤها، أو تم تحريرها أو ببساطة تحميلها باستخدام Aspose.PSD إلى أي تنسيق مدعوم.
دمج الصور
يستخدم هذا المثال فئة Graphics ويوضح كيفية دمج صورتين أو أكثر في صورة واحدة كاملة. لتوضيح العملية، يقوم المثال بإنشاء PsdImage جديد ويقوم برسم الصور على سطح القماش باستخدام الأسلوب الذي تطرحه فئة 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(); | |
} |
توسيع وتقليم الصور
تسمح Aspose.PSD بتوسيع أو تقليم صورة أثناء عملية تحويل الصورة. يحتاج المطور إلى إنشاء مستطيل بإحداثيات X و Y وتحديد عرض وارتفاع مربع المستطيل. تُظهر X، Y والعرض والارتفاع للمستطيل التوسيع أو التقليم للصورة المحملة. إذا كانت هناك حاجة إلى توسيع أو تقليم الصورة أثناء عملية تحويل الصورة، قم باتباع الخطوات التالية:
- إنشاء مثيل من فئة RasterImage وتحميل الصورة الحالية.
- إنشاء مثيل ImageOption class.
- إنشاء مثيل من الفئة 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 (منصة البيانات الوسيعة القابلة للتوسيع) هي معيار ISO. يقوم XMP بتوحيد نموذج البيانات وتنسيق التسلسل والخصائص الأساسية لتعريف ومعالجة البيانات الوسيعة القابلة للتوسيع. كما يوفر إرشادات لتضمين المعلومات XMP في صور شهيرة مثل JPEG، دون تعطيل قراءتها بواسطة التطبيقات التي لا تدعم XMP. باستخدام Aspose.PSD لواجهة برمجة التطبيقات في جافا يمكن للمطورين قراءة أو كتابة بيانات XMP إلى الصور. يظهر هذا المقال كيف يمكن قراءة بيانات 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 لجافا تدعم الآن تحويل الصور في بيئة متعددة المواضيع. تضمن Aspose.PSD لجافا أداء العمليات المحسنة أثناء تنفيذ الكود في بيئة متعددة المواضيع. تنفذ جميع فئات خيارات الصور (مثل BmpOptions و TiffOptions و JpegOptions، إلخ) في Aspose.PSD لجافا واجهة 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 property أثناء العمل في بيئة متعددة المواضيع. يمكن للمطور استخدام هذه الخاصية لتزامن الوصول إلى مصدر التيار. يوضح الكود التالي كيفية استخدام خاصية 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(); | |
} |