拍摄叠加边界内部的图片 [英] Take the picture of what is inside the overlay bounds
问题描述
我正在尝试开发这个拍照的简单应用。一切安好。我唯一能在我的预览中心有一个固定大小的椭圆形图像视图。图像的捕获工作正常,但问题是
我想要捕获图像并自动裁剪它位于里面椭圆形的imageview。我不想保存整个图像,我只想要图像的一部分位于形状内。
现在,我不知道如何继续。在谷歌花了几个小时寻找解决方案后我决定放弃并来到这里。我不知道我怎么能只得到那部分图像所在形状内部(固定的椭圆形图像)。
I'm trying to develop this simple app that takes pictures . Everything is fine. The only thing I have a fixed size oval shaped imageview in center of my preview.Capturing of image is working fine but the problem is I want to capture image and crop it automatically which lies inside the oval shaped imageview.I do not want whole image to be saved , i just want the portion of image which lies inside the shape. Now, I don't know how to proceed.After hours spent on Google for solutions I decided that I had to give up and come here.I am not getting that how can i get only that portion of image which lies inside the shape(That fixed oval shape image).
这是我的代码: -
Here is my code :-
public class MainActivity extends Activity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean cameraview = false;
LayoutInflater inflater = null;
private ImageView ImgContainer;
private Button btn;
private ImageView mIvCaptureImage;
FrameLayout frameLayout;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
frameLayout = (FrameLayout) findViewById(R.id.view);
surfaceView = (SurfaceView) findViewById(R.id.camera_preview);
ImgContainer = (ImageView) findViewById(R.id.Img_container);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// GuideBox box = new GuideBox(MainActivity.this);
// llContainer.addView(box, new LayoutParams(LayoutParams.WRAP_CONTENT,
// LayoutParams.WRAP_CONTENT));
btn = (Button) findViewById(R.id.button);
mIvCaptureImage = (ImageView) findViewById(R.id.imageview1);
btn.setOnClickListener(new OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(View v) {
if (camera != null) {
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}
}
});
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressWarnings("deprecation")
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (cameraview) {
camera.stopPreview();
cameraview = false;
}
if (camera != null) {
try {
setCameraDisplayOrientation(this,
CameraInfo.CAMERA_FACING_BACK, camera);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
cameraview = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressWarnings("deprecation")
private 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);
}
ShutterCallback myShutterCallback = new ShutterCallback() {
public void onShutter() {
// TODO Auto-generated method stub
}
};
PictureCallback myPictureCallback_RAW = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
// TODO Auto-generated method stub
}
};
PictureCallback myPictureCallback_JPG = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
// TODO Auto-generated method stub
Rect rc = getViewPositionRelative();
Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0,
data.length);
Matrix mat = new Matrix();
mat.postRotate(90);
Bitmap correctBmp = Bitmap.createBitmap(bitmapPicture, rc.left,
rc.top, ImgContainer.getWidth(), ImgContainer.getHeight(),
mat, true);
// Bitmap circularBitmap = ImageConverter.getRoundedCornerBitmap(
// correctBmp, 100);
mIvCaptureImage.setImageBitmap(correctBmp);
}
};
public Rect getViewPositionRelative() {
// Locate on screen
int[] location = new int[2];
ImgContainer.getLocationOnScreen(location);
Rect rect = new Rect();
rect.left = location[0];
rect.top = location[1];
rect.right = rect.left + ImgContainer.getWidth();
rect.bottom = rect.top + ImgContainer.getHeight();
return rect;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
cameraview = false;
}
}
第二种方法: -
PictureCallback myPictureCallback_JPG = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, android.hardware.Camera camera) {
Boolean isSDPresent = android.os.Environment
.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
// checking for SD card
if (isSDPresent) {
mediaStorageDir = new File(Environment
.getExternalStorageDirectory().getAbsolutePath(),
IMAGE_DIRECTORY_NAME);
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
}
}
try {
Bitmap userImage = BitmapFactory.decodeByteArray(data, 0,
data.length);
// set file out stream
FileOutputStream out = new FileOutputStream(mediaFile);
// set compress format quality and stream
userImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
userImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
"Please insert SD card !", Toast.LENGTH_LONG).show();
}
if (mediaStorageDir.exists()) {
getPathOfCapturedImage();
}
}
};
private void getPathOfCapturedImage() {
final String ImagePath = mediaFile.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(ImagePath);
int bitWidth = bitmap.getWidth();
int bitHeight = bitmap.getHeight();
// 3. Size of camera preview on screen
int preWidth = surfaceView.getWidth();
int preHeight = surfaceView.getHeight();
Rect rc = getViewPositionRelative();
Matrix mat = new Matrix();
mat.postRotate(90);
int startx = rc.left * bitWidth / preWidth;
int starty = rc.top * bitHeight / preHeight;
int endx = rc.right * bitWidth / preWidth;
int endy = rc.bottom * bitHeight / preHeight;
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, startx, starty,
endx, endy);
mIvCaptureImage.setImageBitmap(resizedBitmap);
}
public Rect getViewPositionRelative() {
// Locate on screen
int[] location = new int[2];
ImgContainer.getLocationOnScreen(location);
Rect rect = new Rect();
rect.left = location[0];
rect.top = location[1];
rect.right = rect.left - ImgContainer.getWidth();
rect.bottom = rect.top - ImgContainer.getHeight();
return rect;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
cameraview = false;
}
Xml: -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".6" >
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/Img_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/eclipce"/>
</FrameLayout>
<ImageView
android:id="@+id/imageview1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight=".2" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_weight=".2"
android:orientation="horizontal" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Capture" />
</LinearLayout>
</LinearLayout>
所以,请如果有人知道任何事情,请告诉我。
So please, if someone knows anything, let me know.
谢谢
推荐答案
一直在玩这个。以下是我解决它的方法:
Have been playing with this a bit. Here is how I solved it:
1)只需拍摄照片,即可获得所有光彩的像素。是的,这比您想要的更多。
1) Just take the picture, with all it's glorious pix. Yes, this is way more then you want.
2)获取叠加的比例。现在你知道在哪里裁剪了。
2) Get the proportions of your overlay. Now you know where to crop.
3)让计算机进行艰苦的计算工作,它很擅长。
3) Let the computer do the hard calculating work, it is good at it.
我的 - 不完整 - 代码:(它的一部分,它在照片上绘制一个矩形来裁剪它)
My - not complete - code: (parts of it, it draws a rectangle over a photo to crop it)
ArrayList<int []> userPoints = new ArrayList<>();
/**
* Method to Crop the image
*
* @param width Width of the output image, in mm.
* @param height Height of the output image, in mm.
*/
private void cropImage(int width, int height) {
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setFilterBitmap(false);
int output_width_start = 0;
int output_width_end = (width * 5) / 2;
int output_height_start = 0;
int output_height_end = (height * 5) / 2;
Matrix matrix = new Matrix();
matrix.setPolyToPoly(
// where to take it from
new float[]{
userPoints.get(0)[0], userPoints.get(0)[1],
userPoints.get(1)[0], userPoints.get(1)[1],
userPoints.get(2)[0], userPoints.get(2)[1],
userPoints.get(3)[0], userPoints.get(3)[1]},
0,
// what it should be
new float[]{
output_width_start, output_height_start,
output_width_end, output_width_start,
output_width_end, output_height_end,
output_height_start, output_height_end},
0, 4);
Uri image_uri = Uri.fromFile(file); // get where the temp is stored
Bitmap bitmap = BitmapFactory.decodeFile(image_uri.getPath());
canvasRectangle.drawBitmap(bitmap, matrix, paint);
}
private void scaleImage(ImageView image) {
Matrix matrix = image.getImageMatrix();
RectF drawableRect = new RectF(userPoints.get(0)[0], userPoints.get(0)[1], 400, 300);
RectF viewRect = new RectF(0, 0, imageViewPhoto.getWidth(), imageViewPhoto.getHeight());
matrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
imageViewPhoto.setImageMatrix(matrix);
}
这篇关于拍摄叠加边界内部的图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!