从相机屏幕上裁剪图像(Android)

4

我想开发一个相机屏幕,包括带框架的相机(请参见第一张图片)。当我拍照时,我不需要完整的图像,我只需要框架内部分的图像(请参见第二张图片)。

enter image description here

enter image description here

我在Github上尝试了许多图像裁剪库。 https://github.com/Yalantis/uCrop https://github.com/ArthurHub/Android-Image-Cropper 我还尝试使用意图调用裁剪。
        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        cropIntent.setDataAndType(uri, "image/*");
        cropIntent.putExtra("crop", "true");
        cropIntent.putExtra("scale", true);
        cropIntent.putExtra("return-data", true);
        startActivityForResult(cropIntent, CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE);

这些并没有帮助我将图像裁剪到框架内。我不想单独裁剪屏幕。请帮我解决问题。提前致谢。


那个框架是另一张图片吗? - Santhosh Joseph
为什么不使用Camera 2 API创建一个Activity,使用可绘制边框XML文件创建一个覆盖层,然后在拍摄后根据该边框裁剪图像呢? - emandt
是的,该框架是相机布局上方的另一张图像。@SanthoshJoseph - Vignes
你能发一下任何参考链接吗?@emandt - Vignes
有什么解决方案吗?我遇到了一些问题。 - R Rifa Fauzi Komara
3个回答

2

您可以使用Surface创建自定义相机,并尝试此操作,希望结果符合您的要求。

 public class MainActivity extends Activity implements SurfaceHolder.Callback {

Camera mCamera;
SurfaceView mPreview; 

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPreview = (SurfaceView)findViewById(R.id.preview);
    mPreview.getHolder().addCallback(this);
    mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    mCamera = Camera.open();
}   
@Override
public void onPause() {
    super.onPause();
    mCamera.stopPreview();
}    
@Override
public void onDestroy() {
    super.onDestroy();
    mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {       
    Parameters parameters = mCamera.getParameters();
    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
    Camera.Size previewSize = previewSizes.get(4); //480h x 720w

    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

    mCamera.setParameters(parameters);

    Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    if(display.getRotation() == Surface.ROTATION_0) {                        
        mCamera.setDisplayOrientation(90);
    } else if(display.getRotation() == Surface.ROTATION_270) {
        mCamera.setDisplayOrientation(180);
    }

    mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(mPreview.getHolder());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    Log.i("PREVIEW","surfaceDestroyed");
}
}

您的XML文件应该长这样:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SurfaceView
        android:id="@+id/preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
  </FrameLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="400px"
        android:layout_marginTop="300px"
        android:layout_marginStart="70px"
        android:layout_marginEnd="70px"
        android:background="@drawable/border" />

    <RelativeLayout
        android:id="@+id/rel_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

     <!---Customize your views and button-->

    </RelativeLayout>
</FrameLayout>

如果您的Android版本高于5.1,则需要在manifests.xml中添加运行时权限,或者您可以手动从应用程序设置中授予权限。

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />

and the response is above code (回应在上面的代码)

enter image description here

(图片链接)

谢谢你的帮助。你尝试过这段代码吗?它不能工作,你把FrameLayout和SurfaceView的id都命名为preview了。 - Vignes
第90行出现异常:尝试调用虚拟方法 'android.view.SurfaceHolder android.view.SurfaceView.getHolder()'。 - Vignes
请在回答之前先运行您的代码。 - Vignes
是的,有权限。 - Vignes
让我们在聊天中继续这个讨论 - Vignes
显示剩余2条评论

2
好的,请试试这个。
    int[] location = new int[2];
    iv_frame.getLocationOnScreen(location);
    int x = location[0];
    int y = location[1];

    Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, iv_frame.getMeasuredWidth() + 160, iv_frame.getMeasuredHeight() + 160); // Adjust the 160 according to your need. In my case the frame has a fixed length and width

拍照 -> 调用此函数并传入相机返回的数据 -> 保存生成的位图 :)


我正在检查这个。 - Vignes
它正在裁剪图像,但在框架内部裁剪得不正确。 - Vignes
实际上,我的框架是LinearLayout。 - Vignes
你懂了吗?还需要更多帮助吗? - Santhosh Joseph
更新你的问题,然后我可以帮助你。 :) - Santhosh Joseph
显示剩余4条评论

-3

这个库应该能解决问题,我经常使用它。它很有效。

https://android-arsenal.com/details/1/4760

它允许你从相册或相机拍摄照片并支持裁剪,而且你不需要写很多代码就能让它工作 ;-)


请清楚理解我的问题。我不需要单独的裁剪功能。我需要在拍照时将框架内的图像裁剪。 - Vignes
哦,好的。非常抱歉。让我回复你。 - Joseph Cobbinah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接