我正在开发一个自定义相机应用程序,它也允许自拍。 当我单击以捕获图像时,图像将在底部被裁剪并保存。我附上我的示例代码
public class CameraActivity extends Activity {
Camera camera;
CameraPreview preview;
Activity act;
Context ctx;
TappableSurfaceView surfaceView;
ImageView image;
private View bottomPanel=null;
public View imagePanel=null;
int cameraId;
private boolean cameraClicked=false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
act = this;
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.new_lay);
try{
image=(ImageView)findViewById(R.id.image);
surfaceView=(TappableSurfaceView)findViewById(R.id.surfaceView);
surfaceView.addTapListener(onTap);
preview = new CameraPreview (this, surfaceView);
preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
((FrameLayout) findViewById(R.id.layout)).addView(preview);
preview.setKeepScreenOn(true);
}catch(Exception e){
GlobalMembers.showAlert(ctx,e);
}
}
@Override
protected void onResume() {
super.onResume();
int numCams = Camera.getNumberOfCameras();
if(numCams > 0){
try{
for (int camNo = 0; camNo < Camera.getNumberOfCameras(); camNo++) {
/* getting front camera */
CameraInfo camInfo = new CameraInfo();
Camera.getCameraInfo(camNo, camInfo);
if (camInfo.facing==
(Camera.CameraInfo.CAMERA_FACING_FRONT)) {
camera = Camera.open(camNo);
cameraId=camNo;
camera.startPreview();
preview.setCamera(camera);
break;
}
}
} catch (RuntimeException ex){
Toast.makeText(ctx, getString(R.string.camera_not_found), Toast.LENGTH_LONG).show();
GlobalMembers.showAlert(ctx,ex);
}
}
else{
Toast.makeText(ctx, getString(R.string.camera_not_found), Toast.LENGTH_LONG).show();
finish();
}
}
@Override
protected void onPause() {
if(camera != null) {
camera.stopPreview();
preview.setCamera(null);
camera.release();
camera = null;
}
super.onPause();
}
private TappableSurfaceView.TapListener onTap=
new TappableSurfaceView.TapListener() {
public void onTap(MotionEvent event) {
Log.d(TAG, "TappableSurfaceView - listener");
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
cameraClicked=true;
}
};
private void resetCam() {
camera.startPreview();
cameraClicked=false;
preview.setCamera(camera);
}
private void refreshGallery(File file) {
Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - jpeg");
if(data!=null){
data=rotateImageBeforeSaving(data);
}
new SaveImageTask().execute(data);
resetCam();
}
};
public int calculateRotation(){
int rotation = this.getWindowManager().getDefaultDisplay()
.getRotation();
Log.d(GlobalMembers.TAG,"Rotation before Saving : "+rotation);
int toRotate=0;
switch(rotation){
case 0:{
toRotate=270;
}
break;
case 1:{
toRotate=0;
}
break;
case 2:{
toRotate=180;
}
break;
case 3:{
toRotate=180;
}
break;
}
return toRotate;
}
public byte[] rotateImageBeforeSaving(byte[] data){
try {
InputStream is = new ByteArrayInputStream(data);
Bitmap bmp = BitmapFactory.decodeStream(is);
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(calculateRotation());
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rotatedBMP.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
} catch (Exception e) {
e.printStackTrace();
Log.e(GlobalMembers.TAG,"Error Occured in CameraActivity",e);
GlobalMembers.showAlert(ctx,e);
return null;
} finally {
}
}
private class SaveImageTask extends AsyncTask<byte[], Void, String> {
@Override
protected void onPostExecute(String imageFilePath) {
// TODO Auto-generated method stub
super.onPostExecute(imageFilePath);
cameraClicked=false;
Intent intent = new Intent(ctx, ViewActivity.class);
intent.putExtra("imageFilePath", imageFilePath);
startActivity(intent);
}
@Override
protected String doInBackground(byte[]... data) {
FileOutputStream outStream = null;
// Write to SD Card
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/smartselfiepro");
dir.mkdirs();
String fileName = "image"+String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
String imageFilePath=dir+File.separator+fileName;
Log.d(GlobalMembers.TAG,"ImageFilePath "+imageFilePath);
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
outStream.flush();
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
refreshGallery(outFile);
return imageFilePath;
} catch (FileNotFoundException e) {
Log.e(GlobalMembers.TAG,"Error Occured in CameraActivity",e);
GlobalMembers.showAlert(ctx,e);
} catch (IOException e) {
Log.e(GlobalMembers.TAG,"Error Occured in CameraActivity",e);
GlobalMembers.showAlert(ctx,e);
} finally {
}
return null;
}
}
/**
* Decode strem.
*
* @param fil
* the fil
* @param selectedImage
* the selected image
* @param mContext
* the m context
* @return the bitmap
*/
public Bitmap rotateImage(Bitmap bmp, String imageUrl) {
if (bmp != null) {
ExifInterface ei;
int orientation = 0;
try {
ei = new ExifInterface(imageUrl);
orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
} catch (IOException e) {
e.printStackTrace();
}
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
Matrix matrix = new Matrix();
Log.d(GlobalMembers.TAG,"Orientation : "+orientation);
int rotation = this.getWindowManager().getDefaultDisplay()
.getRotation();
int toRotate=0;
Log.d(GlobalMembers.TAG,"rotation : "+rotation);
switch(rotation){
case 0:{
toRotate=0;
}
break;
case 1:{
toRotate=0;
}
break;
case 2:{
toRotate=180;
}
break;
case 3:{
toRotate=180;
}
break;
}
matrix.postRotate(toRotate);
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, bmpWidth,
bmpHeight, matrix, true);
return resizedBitmap;
} else {
return bmp;
}
}
}
CameraPreview类
class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
TappableSurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
Context mContext;
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPictureSize;
private int cameraId;
@SuppressWarnings("deprecation")
Preview(Context context, TappableSurfaceView sv) {
super(context);
mContext=context;
mSurfaceView = sv;
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
getCameraId();
}
public void getCameraId(){
try{
for (int camNo = 0; camNo < Camera.getNumberOfCameras(); camNo++) {
CameraInfo camInfo = new CameraInfo();
Camera.getCameraInfo(camNo, camInfo);
if (camInfo.facing==(Camera.CameraInfo.CAMERA_FACING_FRONT)) {
cameraId=camNo;
break;
}
}
} catch (RuntimeException ex){
}
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
Log.d(this.getClass().getName(), "onMeasure Called");
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.d(this.getClass().getName(), "onLayout Called");
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
// setWillNotDraw(false);
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
@Override
protected void onDraw(Canvas canvas) {
Log.d(this.getClass().getName(), "On Draw Called");
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
//boolean portrait = isPortrait();
// if(portrait){
// mCamera.setDisplayOrientation(90);
// }
setRotationParameter((Activity)mContext,parameters);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
// configureCameraParameters(parameters, portrait);
requestLayout();
mCamera.setParameters(parameters);
//mCamera.setDisplayOrientation(degrees)
mCamera.startPreview();
}
}
public boolean isPortrait() {
return (((Activity)mContext).getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
public void setRotationParameter(Activity activity, Camera.Parameters param) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int toRotate=0;
switch(rotation){
case 0:{
toRotate=90;
}
break;
case 1:{
toRotate=0;
}
break;
case 2:{
toRotate=180;
}
break;
case 3:{
toRotate=180;
}
break;
}
Log.d("Preview","Rotation : "+rotation);
rotation = (rotation + 45) / 90 * 90;
// int toRotate = (info.orientation + rotation) % 360;
mCamera.setDisplayOrientation(toRotate);
}
}
我尝试了所有论坛问题而无法解决问题。请帮忙。 此外,在某些手机中,相机预览显示良好且聚焦,但在拍摄时,它会显示模糊图像。我不确定为什么它在不同的相机中有不同的行为。
答案 0 :(得分:1)
经过几个小时的搜索,我发现图像背后的问题被裁剪了。 我没有设置图片大小参数。
不同手机中不同的相机行为仍未解决