JavaRush /Блоги Java /Random-TG /Ҷаҳони байтҳо 1. Кор бо тасвирҳо.
Joysi
Сатҳи

Ҷаҳони байтҳо 1. Кор бо тасвирҳо.

Дар гурӯҳ нашр шудааст
Махсус барои Пеш аз ин ман бо мисолҳои хушк шарҳ додам. Онҳо хоҳиш карданд, ки бо тасвирҳо кор кунанд - онро гиред.
Муайян кардани вазифаи таълимӣ.
Файли графикӣ дода шудааст (jpeg, png...). Бо он якчанд манипуляция кардан ва натиҷаро ба файли дигар навиштан лозим аст. Барои содда кардан, биёед се вазифаро дида бароем: - гирифтани тасвири манфӣ - гирифтани нусхаи сиёҳ ва сафеди тасвир (аз нав танзим кардани ранг) - тағир додани сершавии сабз дар тасвир. Аҳамият диҳед, ки ба ҳамин тариқ, мо метавонем бо илова кардани усулҳои нав, вазифаҳои дигарро иҷро кунем: - баланд бардоштани равшанӣ ё норавшанӣ - тағир додани андозаҳо - ақрабаки соат / муқобor ақрабаки соат гардиш кунед. - ва дигар имкониятҳои Photoshop :) умуман, дар тасвир ҳар алгоритмеро амалӣ кунед, то он даме, ки мо тасаввурот ва дониши кофӣ дар бораи матан дорем (масалан, шумораи гурбаҳои имконпазирро дар расм эътироф кунед).
Як назарияи хушк.
Мо тасвирҳои растериро баррасӣ мекунем (инчунин вектор ва дигарон ҳастанд). Яъне, вақте ки файл ба ғайр аз худи сарлавҳа бо маълумоти хидматӣ, матритсаи росткунҷаи нуқтаҳоро нигоҳ медорад. Монанди экрани телевизиони муосири HD, ки қарори 1920x1080 пиксел дорад ва ҳар як пиксел ҳамчун арзишҳои се ҷузъҳои рангӣ ифода карда мешавад: R(ed), G(reen), B(lue) = Red, Green ва кабуд. Ин рангҳо мустақиланд ва ин модел аз биологияи дарки ранг гирифта шудааст. Дар чашм мо конусҳо ва чубҳо дорем. Конусҳои се навъ (ба яке аз се диапазони дарозии мавҷ вокуниш нишон медиҳанд), чӯбҳо равшании рангро (амплитудаи мавҷи рӯшноӣ) "кор мекунанд". Дар модели RGB, чубҳо барои арзиши ҷузъҳо масъуланд (0 - набудани, 255 - равшантарин нур), ва конусҳо - мутаносибан, дар кадоме аз R / G / B шиддатнокии мувофиқро ҷойгир мекунанд. Масалан: Набудани рӯшноӣ - чубҳо/конусҳо вокуниш намекунанд ва RGB = (0,0,0). Нури сафеди дурахшон - ҳама конусҳо ба таври баробар вокуниш нишон медиҳанд, чубҳо девона мешаванд ва RGB = (255,255,255). Муши хокистарӣ гузашт - ҳама конусҳо яксон реаксия карданд, чубҳо ба ҳисоби миёна ва RGB = (127,127,127). Норинҷи торик - чӯбҳои R ва G вокуниш нишон медиҳанд, чӯбҳо базӯр ҷавоб медиҳанд, RGB = (30, 30, 0) ...
Биёед машқро оғоз кунем.
Ман барои мисоли кор бо byte навиштам, аз ин рӯ code мувофиқи ҳама қоидаҳо сайқал дода нашудааст ва аз оптималӣ дур аст: мо параметрҳои вурудро тафтиш намекунем, санҷиши хатогиҳои пурраро анҷом намедиҳем ва ғайра. Он рост ба пеш, бе рефакторинг навишта шудааст. Диққати асосӣ кор бо byte-битҳо мебошад. Биёед, дар муқоиса бо супоришҳои JavaRush як утorтаи консолро нависем, ки ҳангоми даъват дар сатри фармон бо далелҳои мувофиқ тасвирро тағир медиҳад. Тасвири манбаъ: Китти
занг бо параметрҳои -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