So I currently have a long comic strip and I want to split the image based on white space so none of the text bubbles or backgrounds are cut off.
Currently, I'm splitting the image based on a set size for, e.g. if the image is 100k pixels tall, then it splits the image into 6 equal parts, so the current height (curr) would be 16666.
It then checks at (curr) if all the pixels are white, and also if the row of pixels at (curr+1) is also all white.
And if both rows of pixels are all white, then it logs the height in an array.
If any non-white pixel is detected, then 10 pixels is added to the current height and check again if the rows at (curr)
This continues until (curr) reaches the height of the long image, after which it creates images based on the logged height values.
This is the logic I was going by, however, like all CS things, it didn't work in practice.
I tried this code with multiple images, and I see the split images with top and bottom edges being non-white.
public void smartStitch(ArrayList<BufferedImage> images) throws IOException {
BufferedImage concatImage = new BufferedImage(images.get(0).getWidth(), images.get(0).getHeight(), BufferedImage.TYPE_INT_RGB);
// Stitches if there's multiple images
if (images.size() > 1) {
int concatHeight = 0;
// Gets the total height of the stitches image and prepares a Graphics2D for it
for (BufferedImage b : images) {
concatHeight += b.getHeight();
Graphics2D g2d = b.createGraphics();
g2d.dispose();
}
int heightCurr = 0;
concatImage = new BufferedImage(images.get(0).getWidth(), concatHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = concatImage.createGraphics();
// Draws the images on the Graphics2D
for (BufferedImage b : images) {
g2d.drawImage(b, 0, heightCurr, null);
heightCurr += b.getHeight();
}
g2d.dispose();
}
// Determines how many images to split into
int num;
if (concatImage.getHeight() < 5000) {
num = 2;
} else if (concatImage.getHeight() < 25000) {
num = 4;
} else if (concatImage.getHeight() < 100000) {
num = 6;
} else {
num = 8;
}
// Splits it per white area
new File(outputPath + "\\Azathoth\\").mkdirs();
int parts = concatImage.getHeight() / num;
int end = concatImage.getHeight() / num;
boolean recheck = false;
// Array of pixel heights to split
ArrayList<Integer> cuts = new ArrayList<>();
cuts.add(0);
// Loops while the whole image isn't split yet
while (end+2 < concatImage.getHeight()) {
for (int x = 0; x < concatImage.getWidth(); x++) {
int r = Color.WHITE.getRed();
int g = Color.WHITE.getGreen();
int b = Color.WHITE.getBlue();
int c1 = concatImage.getRGB(x, end + 1);
int r1 = (c1 & 0x00ff0000) >> 16;
int g1 = (c1 & 0x0000ff00) >> 8;
int b1 = c1 & 0x000000ff;
int c2 = concatImage.getRGB(x, end);
int r2 = (c2 & 0x00ff0000) >> 16;
int g2 = (c2 & 0x0000ff00) >> 8;
int b2 = c2 & 0x000000ff;
// If the edge of first image is not white or edge of second image is not white
// Then adds 10 pixels to the checked area and rechecks
if ((r1 != r || g1 != g || b1 != b) || (r2 != r || g2 != g || b2 != b)) {
if (end + 1 > concatImage.getHeight()) {
end = concatImage.getHeight() - 1;
recheck = false; // Doesn't recheck if its at the bottom of the image
} else {
end += 10;
recheck = true;
}
} else {
recheck = false;
}
}
// If recheck is unnecessary, then adds the current height to the pixel height array
// Then adds more pixels to the end variable to check after this loop
if (!recheck) {
cuts.add(end);
if (end + parts > concatImage.getHeight()) {
end = concatImage.getHeight() - 1;
} else {
end = end + parts;
}
}
}
// Sometimes, the last part of the image isn't rendered
cuts.set(cuts.size() - 1, concatImage.getHeight());
System.out.println(cuts.toString());
// Creates the split images based off the image height array
for (int i = 0; i < cuts.size() - 1; i++) {
ImageIO.write(concatImage.getSubimage(0, cuts.get(i), concatImage.getWidth(), cuts.get(i + 1) - cuts.get(i)), "PNG",
new File(outputPath + "\\Azathoth\\" + nameField.getText() + (i+1) + ".png"));
}
// Finished message
Alert a = new Alert(Alert.AlertType.CONFIRMATION);
a.setContentText("Smart Stitch/Split Completed!");
a.showAndWait();
}
User contributions licensed under CC BY-SA 3.0