Skip to content

Instantly share code, notes, and snippets.

@asdf913
Created February 13, 2025 12:03
Show Gist options
  • Save asdf913/c8fabd451c994b407fce746fa629767e to your computer and use it in GitHub Desktop.
Save asdf913/c8fabd451c994b407fce746fa629767e to your computer and use it in GitHub Desktop.
Chop Image by Java
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Collection;
import java.util.function.ObjIntConsumer;
import java.util.function.Predicate;
import javax.imageio.ImageIO;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.function.FailableConsumer;
import org.d2ab.collection.ints.IntCollection;
import org.d2ab.collection.ints.IntList;
import org.d2ab.function.ObjIntPredicate;
public class ChopImage {
public static void main(final String[] args) throws IOException {
//
final Decoder decoder = Base64.getDecoder();
//
final byte[] bs = decoder != null ? decoder.decode(
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAFCAIAAADzBuo/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuM4y7MyAAAAC2ZVhJZklJKgAIAAAABQAaAQUAAQAAAEoAAAAbAQUAAQAAAFIAAAAoAQMAAQAAAAIAAAAxAQIAEAAAAFoAAABphwQAAQAAAGoAAAAAAAAAYAAAAAEAAABgAAAAAQAAAFBhaW50Lk5FVCA1LjEuMwADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlAAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAOmhdjvMuD8gAAACRJREFUGFdj/P//PwNuAJVmZGSE8OEAIs4E4eACBKTx2s3AAAC16Qv//9Y5UgAAAABJRU5ErkJggg=="
.getBytes())
: null;
//
File file = new File("source.png");
//
Files.write(file.toPath(), bs);
//
try (final InputStream is = new ByteArrayInputStream(bs)) {
//
BufferedImage bufferedImage = ImageIO.read(is);
//
System.out.println("source =" + file.getAbsolutePath());
//
System.out.println("source.width =" + getWidth(bufferedImage));
//
System.out.println("source.height=" + getHeight(bufferedImage));
//
ImageIO.write(bufferedImage = chop(bufferedImage), "png", file = new File("result.png"));
//
System.out.println("result =" + file.getAbsolutePath());
//
System.out.println("result.width =" + getWidth(bufferedImage));
//
System.out.println("result.height=" + getHeight(bufferedImage));
//
} // try
//
}
private static BufferedImage chop(final BufferedImage bi) {
//
Integer rgb = null;
//
IntList ilx = null;
//
IntList ily = null;
//
final FailableConsumer<IntList, RuntimeException> failableConsumer = a -> {
//
sortInts(a);
//
for (int i = IterableUtils.size(a) - 2; i > 0; i--) {
//
a.remove(i);
//
} // for
//
};
//
for (int x = 0; x < intValue(getWidth(bi), 0); x++) {
//
for (int y = 0; y < intValue(getHeight(bi), 0); y++) {
//
if (rgb == null && bi != null) {
//
rgb = Integer.valueOf(bi.getRGB(x, y));
//
} else if (rgb != null && rgb.intValue() != bi.getRGB(x, y)) {
//
// ilx
//
testAndAccept((a, b) -> !contains(a, b), ilx = ObjectUtils.getIfNull(ilx, IntList::create), x,
ChopImage::addInt);
//
testAndAccept(a -> IterableUtils.size(a) > 2, ilx, failableConsumer);
//
// ily
//
testAndAccept((a, b) -> !contains(a, b), ily = ObjectUtils.getIfNull(ily, IntList::create), y,
ChopImage::addInt);
//
testAndAccept(a -> IterableUtils.size(a) > 2, ily, failableConsumer);
//
} // if
//
} // for
//
} // for
//
sortInts(ilx);
//
sortInts(ily);
//
final int sizeIlx = IterableUtils.size(ilx);
//
final int sizeIly = IterableUtils.size(ily);
//
if (Boolean.logicalAnd(sizeIlx > 1, sizeIly > 1)) {
//
final int firstX = getInt(ilx, 0, 0);
//
final int firstY = getInt(ily, 0, 0);
//
return ObjectUtils.defaultIfNull(getSubimage(bi, firstX, firstY, getInt(ilx, sizeIlx - 1, 0) - firstX + 1,
getInt(ily, sizeIly - 1, 0) - firstY + 1), bi);
//
} // if
//
return bi;
//
}
private static BufferedImage getSubimage(final BufferedImage instance, final int x, final int y, final int w,
final int h) {
return instance != null ? instance.getSubimage(x, y, w, h) : null;
}
private static int getInt(final IntList instance, final int index, final int defaultValue) {
return instance != null ? instance.getInt(index) : defaultValue;
}
private static <T, E extends Throwable> void testAndAccept(final Predicate<T> predicate, final T value,
final FailableConsumer<T, E> consumer) throws E {
if (predicate != null && predicate.test(value) && consumer != null) {
consumer.accept(value);
}
}
private static boolean contains(final Collection<?> items, final Object item) {
return items != null && items.contains(item);
}
private static <T> void testAndAccept(final ObjIntPredicate<T> predicate, final T t, final int i,
final ObjIntConsumer<T> consumer) {
if (predicate != null && predicate.test(t, i) && consumer != null) {
consumer.accept(t, i);
}
}
private static void addInt(final IntCollection a, final int i) {
if (a != null) {
a.addInt(i);
}
}
private static Integer getHeight(final BufferedImage instance) {
return instance != null ? Integer.valueOf(instance.getHeight()) : null;
}
private static Integer getWidth(final BufferedImage instance) {
return instance != null ? Integer.valueOf(instance.getWidth()) : null;
}
private static int intValue(final Number instance, final int defaultValue) {
return instance != null ? instance.intValue() : defaultValue;
}
private static void sortInts(final IntList instance) {
if (instance != null) {
instance.sortInts();
}
}
}
<!--https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.17.0</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.d2ab/sequence -->
<dependency>
<groupId>org.d2ab</groupId>
<artifactId>sequence</artifactId>
<version>2.3.0</version>
</dependency>
@asdf913
Copy link
Author

asdf913 commented Feb 13, 2025

Read the RGB of the first pixel (x=0,y=0), then first the minimum XY coordinate which has a different RGB value and the maximum XY coordinate. Then chop the image with minimum XY coordinate and maximum XY coordinate.

@asdf913
Copy link
Author

asdf913 commented Feb 13, 2025

Sample Output code

source       =C:\source.png
source.width =10
source.height=5
result       =C:\result.png
result.width =6
result.height=3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment