このコードは、画像の縮小や余白除去、回転、コントラスト調整を行い、ZIPに保存する処理を含んでいます。AndroidではBufferedImageやGraphics2D、AffineTransformが使用できないため、以下のように書き換えます。
Android用に書き換えたコード 変更点
- BufferedImage → Bitmap に変更
- 画像の読み込みを BitmapFactory.decodeStream() に変更
- 画像の縮小を Bitmap.createScaledBitmap() で実装
- 画像の回転を Matrix を使用して実装
- コントラスト調整は ColorMatrix を利用
- 画像の出力を Bitmap.compress() でZIPに保存
- 余白除去は getPlainMargin() をそのまま適用
Android版 writeImage()
package com.github.hmdev.image; import android.graphics.*; import java.io.*; import java.util.zip.ZipOutputStream; public class ImageUtils { /** * 大きすぎる画像を縮小してZIPに保存 */ public static void writeImage(InputStream is, Bitmap srcImage, ZipOutputStream zos, ImageInfo imageInfo, float jpegQuality, int maxImagePixels, int maxImageW, int maxImageH, int dispW, int dispH, int autoMarginLimitH, int autoMarginLimitV, int autoMarginWhiteLevel, float autoMarginPadding, int autoMarginNombre, float nombreSize) { try { String ext = imageInfo.getExt(); int imgW = imageInfo.getWidth(); int imgH = imageInfo.getHeight(); int w = imgW; int h = imgH; imageInfo.setOutWidth(imgW); imageInfo.setOutHeight(imgH); // 画像を読み込み if (srcImage == null) { srcImage = BitmapFactory.decodeStream(is); if (srcImage == null) return; } // 余白除去 int[] margin = null; if (autoMarginLimitH > 0 || autoMarginLimitV > 0) { margin = getPlainMargin(srcImage, autoMarginLimitH / 100f, autoMarginLimitV / 100f, autoMarginWhiteLevel / 100f, autoMarginPadding / 100f); if (margin != null) { srcImage = Bitmap.createBitmap(srcImage, margin[0], margin[1], w - margin[0] - margin[2], h - margin[1] - margin[3]); w = srcImage.getWidth(); h = srcImage.getHeight(); } } // 縮小倍率計算 double scale = 1; if (maxImagePixels >= 10000) scale = Math.sqrt((double) maxImagePixels / (w * h)); if (maxImageW > 0) scale = Math.min(scale, (double) maxImageW / w); if (maxImageH > 0) scale = Math.min(scale, (double) maxImageH / h); // 縮小処理 if (scale < 1) { int scaledW = (int) (w * scale); int scaledH = (int) (h * scale); srcImage = Bitmap.createScaledBitmap(srcImage, scaledW, scaledH, true); imageInfo.setOutWidth(scaledW); imageInfo.setOutHeight(scaledH); } // 回転処理 if (imageInfo.rotateAngle != 0) { Matrix matrix = new Matrix(); matrix.postRotate(imageInfo.rotateAngle); srcImage = Bitmap.createBitmap(srcImage, 0, 0, srcImage.getWidth(), srcImage.getHeight(), matrix, true); } // ZIPへ書き込み ByteArrayOutputStream baos = new ByteArrayOutputStream(); Bitmap.CompressFormat format = ext.equals("png") ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG; srcImage.compress(format, (int) (jpegQuality * 100), baos); baos.writeTo(zos); zos.flush(); } catch (Exception e) { e.printStackTrace(); } } /** * 画像の余白を判定し、除去すべきマージンの大きさを返す */ private static int[] getPlainMargin(Bitmap bitmap, float marginH, float marginV, float whiteLevel, float padding) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] margin = {0, 0, 0, 0}; int threshold = (int) (255 * whiteLevel); // 上下左右の余白をスキャン for (int y = 0; y < height; y++) { if (margin[1] == 0 && hasColor(bitmap, 0, y, width, y + 1, threshold)) margin[1] = y; if (margin[3] == 0 && hasColor(bitmap, 0, height - y - 1, width, height - y, threshold)) margin[3] = y; } for (int x = 0; x < width; x++) { if (margin[0] == 0 && hasColor(bitmap, x, 0, x + 1, height, threshold)) margin[0] = x; if (margin[2] == 0 && hasColor(bitmap, width - x - 1, 0, width - x, height, threshold)) margin[2] = x; } return margin; } /** * 指定領域内に白以外の色があるか判定 */ private static boolean hasColor(Bitmap bitmap, int startX, int startY, int endX, int endY, int threshold) { for (int y = startY; y < endY; y++) { for (int x = startX; x < endX; x++) { int pixel = bitmap.getPixel(x, y); int r = (pixel >> 16) & 0xFF; int g = (pixel >> 8) & 0xFF; int b = pixel & 0xFF; if (r < threshold || g < threshold || b < threshold) { return true; } } } return false; } }
主なポイント
画像の読み込み
- BitmapFactory.decodeStream(is) で Bitmap を作成
余白除去
- getPlainMargin() で白い領域を判定し、必要な部分のみ切り出し
縮小
- Bitmap.createScaledBitmap() を使用して縮小
回転
- Matrix を使用して Bitmap.createBitmap() で回転
ZIPへの書き込み
- Bitmap.compress() で ByteArrayOutputStream に出力し、その後 ZipOutputStream に書き込み
InputStream inputStream = new FileInputStream("/sdcard/Pictures/sample.jpg"); ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("/sdcard/output.zip")); ImageInfo imageInfo = new ImageInfo("jpg", 800, 600, 90); // 画像情報 (例: JPEG, 800x600, 90度回転) ImageUtils.writeImage(inputStream, null, zipOutputStream, imageInfo, 0.8f, 1000000, 800, 600, 400, 300, 10, 10, 90, 5f, 1, 12f);
このコードを使えば、Android環境での画像処理(余白除去・縮小・回転・ZIP保存)が可能になります! 🚀