From a18f387afb01cc7948b8e8ea25f4b61841c653bc Mon Sep 17 00:00:00 2001 From: Zero Date: Sun, 4 Dec 2022 23:24:06 -0500 Subject: [PATCH] Initial implementation of android.graphics.BitmapFactory Only what was needed is implemented, compression method is still untested. --- .../main/java/android/graphics/Bitmap.java | 127 ++++++++++++++++++ .../java/android/graphics/BitmapFactory.java | 36 +++++ 2 files changed, 163 insertions(+) create mode 100644 AndroidCompat/src/main/java/android/graphics/Bitmap.java create mode 100644 AndroidCompat/src/main/java/android/graphics/BitmapFactory.java diff --git a/AndroidCompat/src/main/java/android/graphics/Bitmap.java b/AndroidCompat/src/main/java/android/graphics/Bitmap.java new file mode 100644 index 0000000000..8fcc6a8743 --- /dev/null +++ b/AndroidCompat/src/main/java/android/graphics/Bitmap.java @@ -0,0 +1,127 @@ +package android.graphics; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; + +public final class Bitmap { + private int width; + private int height; + private BufferedImage img; + + public Bitmap(BufferedImage img) { + this.img = img; + this.width = img.getWidth(); + this.height = img.getHeight(); + } + + public BufferedImage getImg() { + return img; + } + + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } + + public enum CompressFormat { + JPEG (0), + PNG (1), + WEBP (2), + WEBP_LOSSY (3), + WEBP_LOSSLESS (4); + + CompressFormat(int nativeInt) { + this.nativeInt = nativeInt; + } + + final int nativeInt; + } + + public enum Config { + ALPHA_8(1), + RGB_565(3), + ARGB_4444(4), + ARGB_8888(5), + RGBA_F16(6), + HARDWARE(7), + RGBA_1010102(8); + + final int nativeInt; + + private static Config sConfigs[] = { + null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE, RGBA_1010102 + }; + + Config(int ni) { + this.nativeInt = ni; + } + + static Config nativeToConfig(int ni) { + return sConfigs[ni]; + } + } + + public static Bitmap createBitmap(int width, int height, Config config) { + BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + return new Bitmap(img); + } + + public boolean compress(CompressFormat format, int quality, OutputStream stream) { + if (stream == null) { + throw new NullPointerException(); + } + + if (quality < 0 || quality > 100) { + throw new IllegalArgumentException("quality must be 0..100"); + } + float qlt = (float) (quality/100); + + String fmt = ""; + if (format == Bitmap.CompressFormat.PNG) { + fmt = "png"; + } else if (format == Bitmap.CompressFormat.JPEG) { + fmt = "jpg"; + } else { + throw new IllegalArgumentException("unsupported compression format!"); + } + + Iterator writers = ImageIO.getImageWritersByFormatName(fmt); + if (!writers.hasNext()) { + throw new IllegalStateException("no image writers found for this format!"); + } + ImageWriter writer = (ImageWriter) writers.next(); + + ImageOutputStream ios; + try { + ios = ImageIO.createImageOutputStream(stream); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + writer.setOutput(ios); + + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(qlt); + + try { + writer.write(null, new IIOImage(img, null, null), param); + ios.close(); + writer.dispose(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + return true; + } +} diff --git a/AndroidCompat/src/main/java/android/graphics/BitmapFactory.java b/AndroidCompat/src/main/java/android/graphics/BitmapFactory.java new file mode 100644 index 0000000000..7285f15a32 --- /dev/null +++ b/AndroidCompat/src/main/java/android/graphics/BitmapFactory.java @@ -0,0 +1,36 @@ +package android.graphics; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class BitmapFactory { + public static Bitmap decodeStream(InputStream is) { + Bitmap bm = null; + + try { + BufferedImage bf = ImageIO.read(is); + bm = new Bitmap(bf); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + return bm; + } + + public static Bitmap decodeByteArray(byte[] data, int offset, int length) { + Bitmap bm = null; + + ByteArrayInputStream bais = new ByteArrayInputStream(data); + try { + BufferedImage bf = ImageIO.read(bais); + bm = new Bitmap(bf); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + return bm; + } +}