JavaRush /Java Blogu /Random-AZ /Baytların dünyası 1. Şəkillərlə işləmək.
Joysi
Səviyyə

Baytların dünyası 1. Şəkillərlə işləmək.

Qrupda dərc edilmişdir
üçün xüsusi Bundan əvvəl mən quru misallarla izah etdim. Şəkillərlə işləməyi xahiş etdilər - alın.
Öyrənmə tapşırığının təyin edilməsi.
Qrafik fayl verilmişdir (jpeg, png...). Onunla bəzi manipulyasiyalar etmək və nəticəni başqa fayla yazmaq lazımdır. Sadələşdirmək üçün üç tapşırığı nəzərdən keçirək: - mənfi şəkil əldə etmək - təsvirin ağ-qara versiyasını əldə etmək (rəngi sıfırla) - təsvirdə yaşıl rəngin doymasını dəyişdirin. Qeyd edək ki, oxşar şəkildə biz yeni üsullar əlavə etməklə digər tapşırıqları yerinə yetirə bilərik: - kəskinliyi və ya bulanıqlığı artırmaq - ölçüləri dəyişdirmək - saat əqrəbi istiqamətində/saat əqrəbinin əksinə fırlatmaq. - və Photoshop-un digər imkanları :) ümumiyyətlə, matan haqqında kifayət qədər təsəvvürümüz və məlumatımız olduğu qədər (məsələn, şəkildəki mümkün pişiklərin sayını tanıyın) şəkildə təsvirə istənilən alqoritm tətbiq edin.
Bir az quru nəzəriyyə.
Raster şəkilləri nəzərdən keçiririk (vektor və başqaları da var). Yəni, fayl, xidmət məlumatı olan başlığa əlavə olaraq, nöqtələrin düzbucaqlı matrisini saxladıqda. 1920x1080 piksel təsvir ölçüsünə malik və hər piksel üç rəng komponentinin dəyərləri kimi təqdim olunan müasir HD TV-nin ekranına bənzər: R(ed), G(reen), B(lue) = Qırmızı, Yaşıl və Mavi. Bu rənglər müstəqildir və bu model rəng qavrayışının biologiyasından götürülmüşdür. Gözümüzdə konuslar və çubuqlar var. Üç növ konuslar (üç dalğa uzunluğu diapazonundan birinə reaksiya verir), çubuqlar rəngin parlaqlığını (işıq dalğasının amplitüdünü) "emal edir". RGB modelində çubuqlar komponentin dəyərinə cavabdehdir (0 - olmaması, 255 - ən parlaq işıq) və konuslar - müvafiq olaraq, R / G / B-dən hansı müvafiq intensivliyi yerləşdirmək üçün. Məsələn: İşığın olmaması - çubuqlar / konuslar reaksiya vermir və RGB = (0,0,0). Parlaq ağ işıq - bütün konuslar bərabər reaksiya verir, çubuqlar dəli olur və RGB = (255,255,255). Boz siçan qaçdı - bütün konuslar bərabər reaksiya verdi, çubuqlar orta reaksiya verdi və RGB = (127,127,127). Tünd narıncı - R və G çubuqları reaksiya verir, çubuqlar çətinliklə cavab verir, RGB=(30, 30, 0) ...
Gəlin məşq etməyə başlayaq.
Baytlarla işləmək nümunəsi üçün yazdım, buna görə kod bütün qaydalara uyğun olaraq cilalanmır və optimaldan uzaqdır: biz giriş parametrlərini yoxlamırıq, tam səhv yoxlaması etmirik və s. Refaktorinq edilmədən düz irəli yazılıb. Əsas diqqət bayt-bitlərlə işləməkdir. Gəlin JavaRush tapşırıqlarına bənzətməklə, müvafiq arqumentlərlə komanda xəttinə çağırılan zaman şəkli dəyişdirən konsol yardım proqramını yazaq. Mənbə şəkli: Kitty
-n kitten.jpg newkitten.jpg parametrləri ilə zəng etmək şəkil yaradacaq: mənfi
-b kitten.jpg newkitten.jpg parametrləri ilə zəng etmək şəkil yaradacaq: qara və ağ pişik
-gr kitten.jpg newkitten.jpg parametrləri ilə zəng etmək şəkil yaradacaq. : alacakaranlıq
Əslində, budur .
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); } } } }
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION