JavaRush /جاوا بلاگ /Random-UR /بائٹس کی دنیا 1. تصاویر کے ساتھ کام کرنا۔
Joysi
سطح

بائٹس کی دنیا 1. تصاویر کے ساتھ کام کرنا۔

گروپ میں شائع ہوا۔
کے لیے خصوصی اس سے پہلے میں نے خشک مثالوں سے وضاحت کی تھی۔ انہوں نے تصاویر کے ساتھ کام کرنے کو کہا - اسے حاصل کریں۔
سیکھنے کا کام ترتیب دینا۔
ایک گرافک فائل دی گئی (jpeg, png...)۔ اس کے ساتھ کچھ ہیرا پھیری کرنا اور نتیجہ دوسری فائل میں لکھنا ضروری ہے۔ آسان بنانے کے لیے، آئیے تین کاموں پر غور کریں: - ایک منفی تصویر حاصل کریں - تصویر کا سیاہ اور سفید ورژن حاصل کریں (رنگ کو دوبارہ ترتیب دیں) - تصویر میں سبز کی سنترپتی کو تبدیل کریں۔ نوٹ کریں کہ اسی طرح ہم، نئے طریقے شامل کر کے، دوسرے کاموں کو لاگو کر سکتے ہیں: - نفاست یا دھندلا پن میں اضافہ - طول و عرض کو تبدیل کریں - گھڑی کی سمت/ مخالف سمت میں گھمائیں۔ - اور فوٹوشاپ کے دیگر امکانات :) عام طور پر، تصویر پر کسی بھی الگورتھم کو لاگو کریں، جہاں تک ہمارے پاس متان کے بارے میں کافی تخیل اور علم ہے (مثال کے طور پر، تصویر میں ممکنہ بلیوں کی تعداد کو پہچانیں)۔
ایک چھوٹا سا خشک نظریہ۔
ہم راسٹر امیجز پر غور کر رہے ہیں (ویکٹر اور دیگر بھی ہیں)۔ یعنی، جب فائل، سروس کی معلومات کے ساتھ ہیڈر کے علاوہ، پوائنٹس کا ایک مستطیل میٹرکس اسٹور کرتی ہے۔ جدید ایچ ڈی ٹی وی کی سکرین کی طرح، جس کی ریزولوشن 1920x1080 پکسلز ہے اور ہر پکسل کو تین رنگوں کے اجزاء کی قدروں کے طور پر دکھایا گیا ہے: R(ed)، G(reen)، B(lue) = سرخ، سبز اور بلیو. یہ رنگ آزاد ہیں اور یہ ماڈل رنگ کے تصور کی حیاتیات سے لیا گیا ہے۔ آنکھ میں ہم کونز اور سلاخیں ہیں۔ تین قسموں کے مخروط (تین طول موج کی حدود میں سے ایک پر ردعمل ظاہر کرتے ہیں)، سلاخیں رنگ کی چمک (روشنی کی لہر کا طول و عرض) پر "عمل" کرتی ہیں۔ آر جی بی ماڈل میں، راڈز اجزاء کی قدر کے لیے ذمہ دار ہیں (0 - غیر موجودگی، 255 - روشن ترین روشنی)، اور کونز - بالترتیب، R/G/B میں سے کس میں متعلقہ شدت کو رکھنا ہے۔ مثال کے طور پر: روشنی کی کمی - سلاخیں/کونز رد عمل ظاہر نہیں کرتے اور RGB = (0,0,0)۔ روشن سفید روشنی - تمام شنک یکساں طور پر رد عمل ظاہر کرتے ہیں، سلاخیں پاگل ہو جاتی ہیں اور RGB = (255,255,255)۔ سرمئی رنگ کا ماؤس بھاگ گیا - تمام شنکوں نے یکساں طور پر رد عمل ظاہر کیا، سلاخوں نے اوسطاً رد عمل ظاہر کیا اور RGB = (127,127,127)۔ گہرا نارنجی - R اور G لاٹھی رد عمل ظاہر کرتی ہے، لاٹھی بمشکل جواب دیتی ہے، RGB=(30, 30, 0) ...
آئیے پریکٹس شروع کریں۔
میں نے بائٹس کے ساتھ کام کرنے کی ایک مثال کے طور پر لکھا ہے، لہذا کوڈ کو تمام اصولوں کے مطابق پالش نہیں کیا گیا ہے اور یہ زیادہ سے زیادہ بہتر نہیں ہے: ہم ان پٹ پیرامیٹرز کی جانچ نہیں کرتے، مکمل غلطی کی جانچ نہیں کرتے، وغیرہ۔ یہ ری فیکٹرنگ کے بغیر سیدھے آگے لکھا گیا تھا۔ بنیادی توجہ بائٹس بٹس کے ساتھ کام کرنا ہے۔ آئیے، جاوا رش ٹاسک کے ساتھ مشابہت کے ساتھ لکھتے ہیں، ایک کنسول یوٹیلیٹی جسے، جب کمانڈ لائن پر مناسب دلائل کے ساتھ بلایا جاتا ہے، تو تصویر میں ترمیم کرتی ہے۔ ماخذ کی تصویر: کٹی
پیرامیٹرز کے ساتھ کال کرنا -n kitten.jpg newkitten.jpg ایک تصویر بنائے گا: منفی
پیرامیٹرز کے ساتھ کال کرنا -b kitten.jpg newkitten.jpg تصویر بنائے گا: سیاہ اور سفید بلی کے بچے
پیرامیٹرز کے ساتھ کال کرنا -gr kitten.jpg newkitten.jpg تصویر بنائے گا۔ : گودھولی
اصل میں، یہ ہے .
package com.joysi.byteworld; import com.sun.imageio.plugins.jpeg.*; import com.sun.imageio.plugins.png.*; import javax.imageio.*; import javax.imageio.stream.*; import java.awt.image.BufferedImage; import java.io.*; public class image { public static void main(String[] args) throws IOException { CoolImage picture = new CoolImage(args[1]); // загружаем файл изображения if ("-n".equals(args[0])) picture.convertToNegative(); if ("-g".equals(args[0])) picture.addColorGreenChannel(-100); if ("-bw".equals(args[0])) picture.convertToBlackAndWhite(); picture.saveAsJpeg(args[2]); } public static class CoolImage{ private int height; // высота изображения private int width; // ширина изображения private int[] pixels; // собственно массив цветов точек составляющих изображение public int getPixel(int x, int y) { return pixels[y*width+x]; } // получить пиксель в формате RGB public int getRed(int color) { return color >> 16; } // получить красную составляющую цвета public int getGreen(int color) { return (color >> 8) & 0xFF; } // получить зеленую составляющую цвета public int getBlue(int color) { return color & 0xFF;} // получить синюю составляющую цвета // Конструктор - создание изображения из file public CoolImage(String fileName) throws IOException { BufferedImage img = readFromFile(fileName); this.height = img.getHeight(); this.width = img.getWidth(); this.pixels = copyFromBufferedImage(img); } // Чтение изображения из file в BufferedImage private BufferedImage readFromFile(String fileName) throws IOException { ImageReader r = new JPEGImageReader(new JPEGImageReaderSpi()); r.setInput(new FileImageInputStream(new File(fileName))); BufferedImage bi = r.read(0, new ImageReadParam()); ((FileImageInputStream) r.getInput()).close(); return bi; } // Формирование BufferedImage из массива pixels private BufferedImage copyToBufferedImage() { BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) bi.setRGB(j, i, pixels[i*width +j]); return bi; } // Формирование массива пикселей из BufferedImage private int[] copyFromBufferedImage(BufferedImage bi) { int[] pict = new int[height*width]; for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) pict[i*width + j] = bi.getRGB(j, i) & 0xFFFFFF; // 0xFFFFFF: записываем только 3 младших byteа RGB return pict; } // Запись изображения в jpeg-формате public void saveAsJpeg(String fileName) throws IOException { ImageWriter writer = new JPEGImageWriter(new JPEGImageWriterSpi()); saveToImageFile(writer, fileName); } // Запись изображения в png-формате (другие графические форматы по аналогии) public void saveAsPng(String fileName) throws IOException { ImageWriter writer = new PNGImageWriter(new PNGImageWriterSpi()); saveToImageFile(writer, fileName); } // Собственно запись file (общая для всех форматов часть). private void saveToImageFile(ImageWriter iw, String fileName) throws IOException { iw.setOutput(new FileImageOutputStream(new File(fileName))); iw.write(copyToBufferedImage()); ((FileImageOutputStream) iw.getOutput()).close(); } // конвертация изображения в негатив public void convertToNegative() { for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) // Применяем логическое отрицание и отбрасываем старший byte pixels[i*width + j] = ~pixels[i*width + j] & 0xFFFFFF; } // конвертация изображения в черно-белый вид public void convertToBlackAndWhite() { for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { // находим среднюю арифметическую интенсивность пикселя по всем цветам int intens = (getRed(pixels[i * width + j]) + getGreen(pixels[i * width + j]) + getBlue(pixels[i * width + j])) / 3; // ... и записываем ее в каждый цвет за раз , сдвигая byteы RGB на свои места pixels[i * width + j] = intens + (intens << 8) + (intens << 16); } } // изменяем интесивность зеленого цвета public void addColorGreenChannel(int delta) { for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { int newGreen = getGreen(pixels[i * width + j]) + delta; if (newGreen > 255) newGreen=255; // Отсекаем при превышении границ byteа if (newGreen < 0) newGreen=0; // В итоговом пикселе R и B цвета оставляем без изменений: & 0xFF00FF // Полученный новый G (зеленый) засунем в "серединку" RGB: | (newGreen << 8) pixels[i * width + j] = pixels[i * width + j] & 0xFF00FF | (newGreen << 8); } } } }
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION