9 Temmuz 2014 Çarşamba

Java ile aynı alana sahip resimlerin pixellerini değiştirmece

Herkese birden fazla merhaba,

Java dilini çok sevmem ama geçen çok ilginç bir koda denk geldim. Biraz da ileride incelemek için kendime not alıyorum aslında. 
Uygulamanın yaptığı, aynı alana (pixel sayısına sahip) 2 resmi birbiri arasında değiştirmek. Yani ilk resimdeki pixelleri kullanarak ikinci resmi orjinale olabildiğince yakın oluşturmak. Eğlenceli bir kod. Detaylar aşağıda. Kod orjinali bu linkten ulaşılabilir.

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;

 
public class PixelRearranger {
    public static void main(String[] args) throws IOException {
        BufferedImage source = ImageIO.read(resource("test1.jpg")); //My names for the files
        BufferedImage palette = ImageIO.read(resource("test2.jpg"));
        BufferedImage result = rearrange(source, palette);
        ImageIO.write(result, "png", resource("result.png"));
    }

    public static BufferedImage rearrange(BufferedImage source,
                                          BufferedImage palette) {
        BufferedImage result = new BufferedImage(source.getWidth(),
                                                 source.getHeight(), BufferedImage.TYPE_INT_RGB);

        //This creates a list of points in the Source image.
        //Then, we shuffle it and will draw points in that order.
        List<Point> samples = getPoints(source.getWidth(), source.getHeight());
        Collections.shuffle(samples);

        //Create a list of colors in the palette.
        List<Integer> colors = getColors(palette);

        while (!samples.isEmpty()) {
            Point currentPoint = samples.remove(0);
            int sourceAtPoint = source.getRGB(currentPoint.x, currentPoint.y);
            int colorIndex = binarySearch(colors, sourceAtPoint);
            int bestColor = colors.remove(colorIndex);
            result.setRGB(currentPoint.x, currentPoint.y, bestColor);
        }
        return result;
    }

    public static List<Point> getPoints(int width, int height) {
        List<Point> points = new ArrayList<>(width * height);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                points.add(new Point(x, y));
            }
        }
        return points;
    }

    public static List<Integer> getColors(BufferedImage img) {
        int width = img.getWidth();
        int height = img.getHeight();
        List<Integer> colors = new ArrayList<>(width * height);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                colors.add(img.getRGB(x, y));
            }
        }
        Collections.sort(colors);
        return colors;
    }

    public static int binarySearch(List<Integer> toSearch, int obj) {
        int index = toSearch.size() >> 1;
        for (int guessChange = toSearch.size() >> 2;
                 guessChange > 0;
                 guessChange >>= 1) {
            int value = toSearch.get(index);
            if (obj == value) {
                return index;
            } else if (obj < value) {
                index -= guessChange;
            } else {
                index += guessChange;
            }
        }
        return index;
    }

    public static File resource(String fileName) { //This method is here solely for my ease of use (I put the files under <Project Name>/Resources/ )
        return new File(System.getProperty("user.dir") + "/Resources/" + fileName);
    }
}

Hiç yorum yok:

Yorum Gönder