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