Camera APIを使用して画像をキャプチャするアプリケーションがあります。この実装はCameraActivityクラスに含まれています。このクラスは、このサイトで見た多くの例の後にモデル化されています。アプリケーションは現在、何千もの電話機で正しく動作しています。しかし、今日、HTC Desire Zユーザーから、自分の画像が一連の縦線としてキャプチャされているという報告がありました(残念ながら、画像を投稿するのに十分なポイントがありませんが、 1つを見るのが好きです)。私のアプリケーション内の画像プレビューと私が保存した画像は歪んでいます。ユーザーは自分のアプリケーションの外で電話カメラを問題なく使用できることも確認しました。私はレビューのためにソースを添付しました。HTC Desire Zで撮影した画像は、一連の縦線を表示します。
ご協力いただければ幸いです。
public class CameraActivity extends Activity {
public static final int FOTO_MODE = 0;
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
private String receiptFileName = null;
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback", "Exception in setPreviewDisplay()", t);
Toast.makeText(CameraActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
if (imageData != null) {
StoreByteImage(CameraActivity.this, imageData, 50, "ImageName");
camera.startPreview();
Intent resultIntent = new Intent();
resultIntent.putExtra(getString(R.string.receiptFileName), receiptFileName);
setResult(FOTO_MODE, resultIntent);
finish();
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.camera_preview);
receiptFileName = getIntent().getStringExtra(getString(R.string.receiptFileName));
ImageView shutterButton = (ImageView) findViewById(R.id.shutterButton);
shutterButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
shutterButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
focusOnly();
return false;
}
});
preview = (SurfaceView) findViewById(R.id.surface_camera);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void onResume() {
super.onResume();
camera = Camera.open();
}
@Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
private void focusOnly() {
String focusMode = camera.getParameters().getFocusMode();
if (focusMode != null
&& (focusMode.equals(Camera.Parameters.FOCUS_MODE_AUTO) || focusMode
.equals(Camera.Parameters.FOCUS_MODE_MACRO))) {
Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
}
};
camera.autoFocus(autoFocusCallback);
}
}
private void takePicture() {
camera.takePicture(null, mPictureCallback, mPictureCallback);
}
private boolean StoreByteImage(Context mContext, byte[] imageData, int quality, String expName) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
FileOutputStream fileOutputStream = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bMap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);
Matrix mat = new Matrix();
mat.postRotate(90);
Bitmap myImage = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), mat, true);
File path = new File(Environment.getExternalStorageDirectory() + ExpenseIt.SD_CARD_PATH_EXTENSION);
path.mkdirs();
fileOutputStream = new FileOutputStream(path + "/" + determineReceiptName());
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
myImage.compress(CompressFormat.JPEG, quality, bos);
bos.flush();
bos.close();
} catch (Exception e) {
FailureDialogFactory.getInstance().handleFailure(this, "Failure storing camera image.", e);
}
} else {
FailureDialogFactory.getInstance().handleFailure(this,
"Unable capture receipts while SD card is not available or phone is connected to computer.", null);
}
return true;
}
private String determineReceiptName() {
if (receiptFileName == null) {
receiptFileName = Calendar.getInstance().getTimeInMillis() + ".jpg";
}
return receiptFileName;
}
アイデアをありがとうが、これは機能しませんでした。あなたのアイデアをgetBestPreviewSize()メソッドに組み込みましたが、結果はまだ垂直線です。 –
@ user657719明確にするために、上記の4つの解像度サイズはsetPreviewSize()メソッドではなく* setPictureSize()メソッドに渡されます。問題を回避する別の方法が見つかりましたか? – Siddharth
メイト、許容誤差を0.1に設定すると、サポートされている画像サイズがすべて1.3のギャラクシーエースのようなデバイスでは機能しなくなります。 – dumbfingers