JavaRush /Java блогы /Random-KK /Байттар әлемі 1. Суреттермен жұмыс.
Joysi
Деңгей

Байттар әлемі 1. Суреттермен жұмыс.

Топта жарияланған
үшін арнайы Бұған дейін мен құрғақ мысалдармен түсіндірдім. Олар суреттермен жұмыс істеуді сұрады - алыңыз.
Оқу тапсырмасын қою.
Графикалық файл берілген (jpeg, png...). Онымен кейбір манипуляциялар жасап, нәтижені басқа файлға жазу керек. Жеңілдету үшін үш тапсырманы қарастырайық: - теріс суретті алу - кескіннің ақ-қара нұсқасын алу (түсін қалпына келтіру) - кескіндегі жасыл түстің қанықтылығын өзгерту. Осыған ұқсас жолмен біз жаңа әдістерді қосу арқылы басқа тапсырмаларды орындай алатынымызды ескеріңіз: - айқындықты немесе бұлыңғырлықты арттыру - өлшемдерді өзгерту - сағат тілімен/сағат тіліне қарсы бұру. - және Photoshop-тың басқа мүмкіндіктері :) жалпы алғанда, бізде матан туралы қиялымыз және біліміміз жеткілікті болса, суретке кез келген алгоритмді енгізіңіз (мысалы, суреттегі мүмкін мысықтардың санын тану).
Кішкене құрғақ теория.
Біз растрлық кескіндерді қарастырамыз (векторлық және басқалары да бар). Яғни, файл, қызметтік ақпараты бар тақырыптың өзіне қосымша нүктелердің тікбұрышты матрицасын сақтайды. 1920x1080 пиксел рұқсаты бар және әр пиксель үш түсті құрамдастардың мәндері ретінде ұсынылған қазіргі заманғы HD теледидарының экранына ұқсас: 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 тапсырмаларына ұқсастық бойынша пәрмен жолында тиісті дәлелдермен шақырылған кезде кескінді өзгертетін консольдік қызметтік бағдарламаны жазайық. Бастапқы сурет: Китти
-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