JavaRush /Java Blog /Random-TK /Baýtlar dünýäsi 1. Suratlar bilen işlemek.
Joysi
Dereje

Baýtlar dünýäsi 1. Suratlar bilen işlemek.

Toparda çap edildi
Forörite Ondan öň gury mysallar bilen düşündirdim. Suratlar bilen işlemegi haýyş etdiler - alyň.
Okuw meselesini düzmek.
Grafiki faýl berilýär (jpeg, png ...). Munuň bilen käbir manipulýasiýa etmeli we netijäni başga bir faýla ýazmaly. Simplönekeýleşdirmek üçin üç meseläni gözden geçireliň: - otrisatel şekil alyň - suratyň ak-gara görnüşini alyň (reňkini üýtgediň) - şekilde ýaşyl doýgunlygy üýtgediň. Şuňa meňzeş usulda, täze usullary goşmak bilen, beýleki meseleleri ýerine ýetirip biljekdigimize üns beriň: - ýitiligi ýa-da bulaşyklygy ýokarlandyrmak - ölçegleri üýtgetmek - sagat ugruna / sagat tersine aýlanmak. - we Photoshop-yň beýleki mümkinçilikleri :) umuman, matan hakda ýeterlik hyýalymyz we bilimimiz bar bolsa (mysal üçin, suratda mümkin pişikleriň sanyny tanamak) şekilde islendik algoritmi durmuşa geçiriň.
Biraz gury teoriýa.
Has çalt şekilleri göz öňünde tutýarys (wektor we beýlekiler hem bar). .Agny, faýl, hyzmat maglumatlary bilen sözbaşydan başga-da, nokatlaryň gönüburçly matrisasyny saklaýar. 1920x1080 piksel durulykda we her piksel üç reňkli komponentiň bahasy hökmünde görkezilýär: R (ed), G (reen), B (lue) = Gyzyl, Greenaşyl we Gök. Bu reňkler garaşsyz we bu model reňk duýgusynyň biologiýasyndan alnan. Gözümizde konuslar we çybyklar bar. Üç görnüşiň konuslary (üç tolkun uzynlygy diapazonynyň birine jogap beriň), çybyklar reňkiň ýagtylygyny (ýagtylyk tolkunynyň amplitudasy) “gaýtadan işleýär”. RGB modelinde çybyklar degişlilikde R / G / B-de degişli intensiwligi ýerleşdirmek üçin komponentiň (0 - ýoklugy, 255 - iň ýagty yşyk) we konuslaryň bahasy üçin jogapkärdir. Mysal üçin: lightagtylygyň ýetmezçiligi - çybyklar / konuslar reaksiýa bermeýär we RGB = (0,0,0). Açyk ak çyra - ähli konuslar deň reaksiýa berýär, çybyklar däli bolýar we RGB = (255,255,255). Çal syçanjygyň içinden geçdi - ähli konuslar deň derejede reaksiýa berdiler, çybyklar ortaça reaksiýa berdiler we RGB = (127,127,127). Gara mämişi - R we G taýaklary reaksiýa berýär, taýaklar zordan jogap berýär, RGB = (30, 30, 0) ...
Türgenleşip başlalyň.
Baýt bilen işlemegiň mysaly üçin ýazdym, şonuň üçin kod ähli düzgünlere görä ýuwulmaýar we optimal däl: giriş parametrlerini barlamaýarys, ýalňyşlygy doly barlamaýarys we ş.m. Göçürilmän göni öňe ýazyldy. Esasy üns baýt-bit bilen işlemekdir. JavaRush meselelerine meňzeşlik bilen buýruk setirine degişli argumentler bilen çagyrylanda şekili üýtgedýän konsol kömekçi enjamyny ýazalyň. Çeşme şekili: Kitti
-n kitten.jpg parametrleri bilen jaň etmek newkitten.jpg surat döreder: otrisatel
parametrleri bilen jaň etmek -b kitten.jpg newkitten.jpg surat döreder: ak we ak pişik
parametrleri bilen jaň etmek -gr kitten.jpg newkitten.jpg surat döreder : garaňky
Aslynda bu .
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); } } } }
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION