現在、Androidカメラを使用しようとしていますが、テストプロジェクトはかなり進んでいます。GingerbreadAndroidを搭載したHTCDesireSでテストしたところ、完全に正常に機能しました。ただし、ICSに更新した後、テストアプリで撮影した写真には、奇妙な垂直線しか表示されません(まったく同じコードです)。これが突然作成された画像です:http: //imageshack.us/photo/my-images/191/rebuilder1.jpg/
これが私のコードです(クラス全体):
package inter.rebuilder;
import inter.rebuilder.R;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
public class CameraView extends Activity implements SurfaceHolder.Callback,
OnClickListener {
static final int FOTO_MODE = 0;
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
private Context mContext = this;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
//boolean hasCam = checkCameraHardware(mContext);
Log.e(TAG, "onCreate");
Bundle extras = getIntent().getExtras();
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PreviewCallback mPreviewCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
int width = parameters.getPreviewSize().width;
int height = parameters.getPreviewSize().height;
ByteArrayOutputStream outstr = new ByteArrayOutputStream();
Rect rect = new Rect(0, 0, width, height);
YuvImage yuvimage=new YuvImage(data,ImageFormat.NV21,width,height,null);
yuvimage.compressToJpeg(rect, 100, outstr);
Bitmap bmp = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
}
};
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
if (imageData != null) {
Intent mIntent = new Intent();
storeByteImage(mContext, imageData, 100);
try {
mCamera.unlock();
mCamera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setResult(FOTO_MODE, mIntent);
startCameraPreview();
//mCamera.startPreview();
//finish();
//Intent intent = new Intent(CameraView.this, AndroidBoxExample.class);
//CameraView.this.startActivity(intent);
}
}
};
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
}
protected void onStop() {
Log.e(TAG, "onStop");
super.onStop();
}
public void surfaceCreated(SurfaceHolder holder) {
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open();
//mCamera.unlock();
//mCamera.setDisplayOrientation(180);
}
private void startCameraPreview() {
Camera.Parameters p = mCamera.getParameters();
p.setPictureFormat(PixelFormat.JPEG);
//p.setPreviewSize(w, h);
List<Size> list = p.getSupportedPreviewSizes();
Camera.Size size = list.get(0);
p.setPreviewSize(size.width, size.height);
mCamera.setParameters(p);
mCamera.startPreview();
mPreviewRunning = true;
}
private void startCameraPreview(SurfaceHolder holder) {
Camera.Parameters p = mCamera.getParameters();
//p.setPreviewSize(w, h);
List<Size> list = p.getSupportedPreviewSizes();
Camera.Size size = list.get(0);
p.setPreviewSize(size.width, size.height);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
//setCameraDisplayOrientation(this, 0, mCamera);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning) {
mCamera.stopPreview();
mPreviewRunning = false;
}
startCameraPreview(holder);
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
super.onConfigurationChanged(newConfig);
}
@Override
public void onContentChanged() {
// TODO Auto-generated method stub
super.onContentChanged();
}
@Override
public void onContextMenuClosed(Menu menu) {
// TODO Auto-generated method stub
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
super.onContextMenuClosed(menu);
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
public void onClick(View arg0) {
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
private static File createDir() throws IOException {
String nameDir = "rebuilder";
File extStorageDir = Environment.getExternalStorageDirectory();
File sdImageMainDirectory = extStorageDir; //new File("/sdcard");
File dirFile = new File(sdImageMainDirectory.getPath()+"/"+nameDir);
boolean fileExisted = dirFile.exists();
if(!fileExisted) {
dirFile.mkdirs();
}
return dirFile;
}
private static File createFile(String name, File dirFile) throws IOException {
int counter = 1;
String fileName = name + counter+".jpg";
File imageFile = new File(dirFile.getPath()+"/"+fileName);
while(imageFile.exists()) {
counter = counter + 1;
fileName = name + counter+".jpg";
imageFile = new File(dirFile.getPath()+"/"+fileName);
}
imageFile.createNewFile();
return imageFile;
}
static Bitmap image1 = null;
static Bitmap image2 = null;
public static void blendTest(Bitmap myImage) throws IOException {
if(image1 == null && image2 == null) {
image1 = myImage;
return;
}
if(image1 != null && image2 != null) {
image2 = null;
image1 = myImage;
return;
}
if(image1 != null && image2 == null) {
image2 = myImage;
}
int width = Math.min(image1.getWidth(), image2.getWidth());
int height = Math.min(image1.getHeight(), image2.getHeight());
int[][] pixels1 = new int[width][height];
int[][] pixels2 = new int[width][height];
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
pixels1[i][j] = image1.getPixel(i, j);
}
}
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
pixels2[i][j] = image2.getPixel(i, j);
}
}
Bitmap image3 = Bitmap.createBitmap(width, height, image1.getConfig());
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
int color1 = pixels1[i][j];
int color2 = pixels2[i][j];
int red1 = Color.red(color1);
int red2 = Color.red(color2);
int green1 = Color.green(color1);
int green2 = Color.green(color2);
int blue1 = Color.blue(color1);
int blue2 = Color.blue(color2);
int newColor = Color.rgb((red1 + red2)/2, (green1 + green2)/2, (blue1 + blue2)/2);
image3.setPixel(i, j, newColor);
}
}
File dirFile = createDir();
File newBlend = createFile("blend", dirFile);
FileOutputStream fileOutputStream = new FileOutputStream(newBlend);
BufferedOutputStream bos = new BufferedOutputStream(
fileOutputStream);
image3.compress(CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
}
// public static void setCameraDisplayOrientation(Activity activity,
// int cameraId, android.hardware.Camera camera) {
// android.hardware.Camera.CameraInfo info =
// new android.hardware.Camera.CameraInfo();
// android.hardware.Camera.getCameraInfo(cameraId, info);
// int rotation = activity.getWindowManager().getDefaultDisplay()
// .getRotation();
// int degrees = 0;
// switch (rotation) {
// case Surface.ROTATION_0: degrees = 0; break;
// case Surface.ROTATION_90: degrees = 90; break;
// case Surface.ROTATION_180: degrees = 180; break;
// case Surface.ROTATION_270: degrees = 270; break;
// }
//
// int result;
// if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// result = (info.orientation + degrees) % 360;
// result = (360 - result) % 360; // compensate the mirror
// } else { // back-facing
// result = (info.orientation - degrees + 360) % 360;
// }
// camera.setDisplayOrientation(result);
// }
public static boolean storeByteImage(Context mContext, byte[] imageData, int quality) {
FileOutputStream fileOutputStream = null;
try {
File dirFile = createDir();
File imageFile = createFile("rebuilder", dirFile);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 5; //5
options.inDither = false; // Disable Dithering mode
options.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
options.inInputShareable = true; // Which kind of reference will be
// used to recover the Bitmap
// data after being clear, when
// it will be used in the future
options.inTempStorage = new byte[32 * 1024];
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
imageData.length,options);
int orientation;
// others devices
if(myImage.getHeight() < myImage.getWidth()){
orientation = 90;
} else {
orientation = 0;
}
Bitmap bMapRotate;
if (orientation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
bMapRotate = Bitmap.createBitmap(myImage, 0, 0, myImage.getWidth(),
myImage.getHeight(), matrix, true);
} else
bMapRotate = Bitmap.createScaledBitmap(myImage, myImage.getWidth(),
myImage.getHeight(), true);
//blendTest(myImage);
fileOutputStream = new FileOutputStream(imageFile);
BufferedOutputStream bos = new BufferedOutputStream(
fileOutputStream);
bMapRotate.compress(CompressFormat.JPEG, quality, bos);
if (bMapRotate != null) {
bMapRotate.recycle();
bMapRotate = null;
}
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("SD Card not ready");
}
return true;
}
}
カメラハードウェアの権限と向きの横向きは、Androidマニフェストで設定されます。ここで私を助けてください。