KDP(電子出版)のメモ 急急如律令

Amazon Kindleダイレクト・パブリッシングでの電子出版や電子書籍の作成販売について、文章やイラストの作成や編集方法について書いています。

Androidで画像の情報を取得したい。

Androidで画像の情報を取得したい。

imageioがAndroidで使えないので、書き換える必要がある。

ImageInfo.java

次のコードAndroid向けに書き換えて

このコードは、Java SE の ImageIO を使用して画像の情報を取得するものですが、Android では ImageIO が利用できません。 Android では BitmapFactory を使って画像の幅や高さを取得できます。

Android 向けに書き換えた ImageInfo クラス 変更点 ImageIO の代わりに BitmapFactory を使用 BitmapFactory.Options を使い、画像のデコードなしでサイズ情報のみ取得。 FileInputStream の代わりに ContentResolver をサポート File だけでなく Uri からの読み込みを可能にする。 BufferedImage 関連のコードを削除 BufferedImage は Android では使用できないため、Bitmap に変更。

package io.github.kyukyunyorituryo.aozoraepub3.info;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.net.Uri;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/** 画像情報クラス */
public class ImageInfo {
    /** ファイルのID 0001 */
    private String id;
    /** 出力ファイル名 拡張子付き 0001.png */
    private String outFileName;
    /** 画像フォーマット png jpg gif */
    private String ext;

    /** 画像幅 */
    private int width = -1;
    /** 画像高さ */
    private int height = -1;

    /** 出力画像幅 */
    private int outWidth = -1;
    /** 出力画像高さ */
    private int outHeight = -1;

    /** カバー画像ならtrue */
    private boolean isCover;

    /** 回転角度(右 90° 左 -90°) */
    private int rotateAngle = 0;

    /** 画像の情報を生成
     * @param ext png, jpg, gif の拡張子
     */
    public ImageInfo(String ext, int width, int height) {
        this.ext = ext.toLowerCase();
        this.width = width;
        this.height = height;
    }

    /** ファイルから画像情報を取得 */
    public static ImageInfo getImageInfo(File imageFile) throws IOException {
        return getImageInfo(new FileInputStream(imageFile), getFileExtension(imageFile));
    }

    /** Uri から画像情報を取得 (Android用)
     * @param context Androidの `Context`
     * @param imageUri 画像の `Uri`
     */
    public static ImageInfo getImageInfo(Context context, Uri imageUri) throws IOException {
        ContentResolver resolver = context.getContentResolver();
        InputStream is = resolver.openInputStream(imageUri);
        if (is == null) {
            throw new IOException("Failed to open InputStream from Uri");
        }
        return getImageInfo(is, getFileExtension(imageUri.toString()));
    }

    /** InputStream から画像情報を取得 */
    private static ImageInfo getImageInfo(InputStream is, String ext) throws IOException {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; // 画像のデコードはせず、サイズのみ取得
        BitmapFactory.decodeStream(is, null, options);
        is.close();
        return new ImageInfo(ext, options.outWidth, options.outHeight);
    }

    /** ファイル名やパスから拡張子を取得 */
    private static String getFileExtension(String filename) {
        int lastDot = filename.lastIndexOf('.');
        if (lastDot == -1) return "";
        return filename.substring(lastDot + 1).toLowerCase();
    }

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getOutFileName() { return outFileName; }
    public void setOutFileName(String file) { this.outFileName = file; }

    public String getExt() { return this.ext; }
    public void setExt(String ext) { this.ext = ext; }

    /** MIME 形式(image/png)のフォーマットを取得 */
    public String getFormat() {
        return "image/" + (this.ext.equals("jpg") ? "jpeg" : this.ext);
    }

    public boolean getIsCover() { return this.isCover; }
    public void setIsCover(boolean isCover) { this.isCover = isCover; }

    public int getWidth() { return width; }
    public void setWidth(int width) { this.width = width; }

    public int getHeight() { return height; }
    public void setHeight(int height) { this.height = height; }

    public int getOutWidth() { return outWidth; }
    public void setOutWidth(int outWidth) { this.outWidth = outWidth; }

    public int getOutHeight() { return outHeight; }
    public void setOutHeight(int outHeight) { this.outHeight = outHeight; }
}

変更点の詳細 BufferedImage → BitmapFactory に変更

java コピーする 編集する BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, options); inJustDecodeBounds = true を指定することで、実際に画像をデコードせずに width と height を取得。 メモリを節約しながら画像情報を取得できる。 Android の Uri をサポート

java コピーする 編集する ContentResolver resolver = context.getContentResolver(); InputStream is = resolver.openInputStream(imageUri); Uri から InputStream を取得し、BitmapFactory.decodeStream() で処理。 Android では File ではなく Uri を扱うことが多いため、Uri からの取得メソッドを追加。 拡張子の取得を getFileExtension() で統一

java コピーする 編集する private static String getFileExtension(String filename) { int lastDot = filename.lastIndexOf('.'); if (lastDot == -1) return ""; return filename.substring(lastDot + 1).toLowerCase(); } File だけでなく Uri に対しても利用可能にするため、拡張子取得の処理を関数化。

MainActivity での使用例 1. File から情報を取得 java コピーする 編集する File imageFile = new File("/sdcard/Pictures/sample.jpg"); try { ImageInfo info = ImageInfo.getImageInfo(imageFile); Log.d("ImageInfo", "Width: " + info.getWidth() + ", Height: " + info.getHeight()); } catch (IOException e) { e.printStackTrace(); } 2. Uri から情報を取得 java コピーする 編集する Uri imageUri = Uri.parse("content://media/external/images/media/12345"); try { ImageInfo info = ImageInfo.getImageInfo(this, imageUri); Log.d("ImageInfo", "Width: " + info.getWidth() + ", Height: " + info.getHeight()); } catch (IOException e) { e.printStackTrace(); } まとめ BitmapFactory を使用し、メモリを節約しながら画像のサイズを取得 File だけでなく、Android の Uri からも画像情報を取得可能に getFileExtension() を用いて、ファイル名やパスから拡張子を判定 Android に適した ContentResolver を活用し、Uri に対応 この実装なら、Android で画像情報を安全かつ効率的に取得できます! 🚀