カメラ プレビューから生成されたビットマップのトリミングに成功し、生成された小さなビットマップを SD カードに保存しています。大きなビットマップとトリミングされたビットマップの両方を作成するときは、それらをBitmap.Config.ARGB_8888に構成しています。しかし、sdcard からそのイメージをロードすると、ビットマップの構成が RGB_565 に変更されます。ARGB_8888 にする必要があります。これは ICS 以前のデバイスで発生します (HoneyComb を持っていないので、何と言えばよいかわかりません)。
- モトローラ デファイ (2.3.4)
- ソニーエリクソン S (2.3.4)
- ソニー エリクソン ライブ ウォークマン (2.3.4)
- サムスン ギャラクシー ミニ (2.2.1)
- サムスン スピカ (2.2)
奇妙なのは、トリミングされたビットマップを作成した後、その構成を照会していて、ログに ARGB_8888 と表示されていることです。
私がテストしたすべての ICS および JellyBean デバイスでは、ロードされたビットマップが常に ARGB_8888 構成であるため、これは見られません。
以下は、カメラからのバイト配列を指定して画像をトリミングおよび構成する方法です。
@SuppressLint("SimpleDateFormat")
@Override
protected String doInBackground(byte[]... params) {
/***
* Will return the file name where we created the image
* */
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");
String fileName = sdf.format(new Date()) + ".jpeg";
File cameraRoot = Utils.getFileCacheDir(context, WIMSConstants.FileCacheDirs.CAMERA_CAPTURED);
if (!cameraRoot.exists() || !cameraRoot.isDirectory()) {
if (!cameraRoot.mkdir()) {
Log.e("WIMSOcrCamera", "Unable to create folder name " + cameraRoot.getAbsolutePath());
return null;
}
}
/**
* The target file name where to write
* **/
File targetFile = new File(cameraRoot, fileName);
FileOutputStream fos = null;
try {
byte[] cameraByteArray = params[0];
Options opts = new Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeByteArray(cameraByteArray, 0, cameraByteArray.length, opts);
/**
* Below log prints 'ARGB_8888' no matter the OS I am running
* */
Log.d(TAG_LOG, "Big camera image config: " + bitmap.getConfig());
fos = new FileOutputStream(targetFile);
/**
* screenDims is a two array giving the full size image (full screen size)
* **/
int fullSizeWidth = screenDims[0];
int fullSizeHeight = screenDims[1];
/**
* viewPortrect is a Rect that defines the area from the screen that I would like to crop.
*
* rectLeft, rectTop, rectWidth and rectHeight are the desired dimensions of the cropped image relative to the above created bitmap (bitmap).
* */
int rectLeft = bitmap.getWidth() * viewPortRect.left / fullSizeWidth;
int rectTop = bitmap.getHeight() * viewPortRect.top / fullSizeHeight;
int rectWidth = bitmap.getWidth() * viewPortRect.width() / fullSizeWidth;
int rectHeight = bitmap.getHeight() * viewPortRect.height() / fullSizeHeight;
int[] array = new int[rectWidth * rectHeight];
bitmap.getPixels(array, 0, rectWidth, rectLeft, rectTop, rectWidth, rectHeight);
bitmap.recycle();
/**
* Hurray! we have the cropped image int[] pixel data
* **/
bitmap = Bitmap.createBitmap(array, rectWidth, rectHeight, Config.ARGB_8888);
/**
* Bitmap.Config.ARGB_8888.equals(bitmap.getConfig()) ALWAYS evaluates to true no matter the device OS I am running.
* **/
Log.d(TAG_LOG, "generated smaller file ... config: " + bitmap.getConfig() + "; is onfig.ARGB_8888 equals: " + (Bitmap.Config.ARGB_8888.equals(bitmap.getConfig())));
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
bitmap.recycle();
Log.d(TAG_LOG, "DONE creating the cropped image ...");
return targetFile.getAbsolutePath();
} catch (IOException ex) {
Log.e(TAG_LOG, null, ex);
} catch (Throwable th) {
Log.e(TAG_LOG, null, th);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ignored) {
}
}
}
return null;
}
(サービスからの) fileURI を指定して、SDCard からイメージをロードします。
Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), fileUri);
/**
* "RGB_565" for pre-ICS always
* **/
Log.d(LOG_TAG, "bitmap config: " + bmp.getConfig());
これは既知の問題ですか? トリミングされたビットマップをインテントを通じて最終レシーバーに渡す以外に回避策はありますか?
ありがとう!