JavaRush /Blog Jawa /Random-JV /World of Bytes 1. Nggarap gambar.
Joysi
tingkat

World of Bytes 1. Nggarap gambar.

Diterbitake ing grup
Khusus kanggo Sadurunge iki, aku nerangake karo conto garing. Padha takon kanggo bisa karo gambar - njaluk iku.
Nyetel tugas sinau.
Diwenehi file grafis (jpeg, png...). Sampeyan kudu nindakake sawetara manipulasi lan nulis asil menyang file liyane. Kanggo nyederhanakake, ayo nimbang telung tugas: - entuk gambar negatif - entuk versi ireng lan putih saka gambar (reset werna) - ngganti saturasi ijo ing gambar. Elinga yen kanthi cara sing padha, kita bisa, kanthi nambahake metode anyar, ngleksanakake tugas liyane: - nambah ketajaman utawa blur - ngganti dimensi - muter searah jarum jam/lawan arah jarum jam. - lan kemungkinan liyane saka Photoshop :) ing umum, ngleksanakake algoritma sembarang ing gambar, minangka adoh kita duwe cukup bayangan lan kawruh matan (contone, ngenali nomer bisa kucing ing gambar).
A teori garing sethitik.
Kita nimbang gambar raster (ana uga vektor lan liya-liyane). Sing, nalika file, saliyane kanggo header dhewe karo informasi layanan, nyimpen matriks persegi dowo TCTerms. Padha karo layar TV HD modern, sing nduweni resolusi 1920x1080 piksel lan saben piksel dituduhake minangka nilai saka telung komponen warna: R(ed), G(reen), B(lue) = Abang, Ijo lan Biru. Werna iki bebas lan model iki dijupuk saka biologi persepsi warna. Ing mripat kita duwe cones lan rod. Kerucut saka telung jinis (reaksi karo siji saka telung dawa gelombang sing cocog), rod "ngolah" padhang warna (amplitudo gelombang cahya). Ing model RGB, rod tanggung jawab kanggo Nilai saka komponen (0 - anané, 255 - cahya padhang), lan cones - mungguh, kang R / G / B kanggo nyeleh kakiyatan cocog. Contone: Kurang cahya - rod / cones ora reaksi lan RGB = (0,0,0). Cahya putih padhang - kabeh cones nanggepi roto-roto, rod dadi edan lan RGB = (255.255.255). Mouse abu-abu mlayu liwat - kabeh cones nanggepi roto-roto, rod reacted rata-rata lan RGB = (127,127,127). Oranye peteng - R lan G teken bereaksi, teken meh ora nanggapi, RGB=(30, 30, 0) ...
Ayo padha miwiti latihan.
Aku nulis kanggo conto nggarap bait, supaya kode kasebut ora dipoles miturut kabeh aturan lan adoh saka optimal: kita ora mriksa parameter input, ora mriksa kesalahan lengkap, lsp. Iki ditulis terus maju, tanpa refactoring. Fokus utama nggarap bit-bit. Ayo nulis, kanthi analogi karo tugas JavaRush, sarana konsol sing, nalika diarani baris perintah kanthi argumen sing cocog, ngowahi gambar kasebut. Gambar sumber: Kitty
nelpon nganggo parameter -n kitten.jpg newkitten.jpg bakal nggawe gambar: negatif
nelpon nganggo parameter -b kitten.jpg newkitten.jpg bakal nggawe gambar: kucing ireng lan putih
nelpon nganggo parameter -gr kitten.jpg newkitten.jpg bakal nggawe gambar : surup
Sejatine iku .
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); } } } }
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION