Android自定义相机 - 在矩形

时间:2017-01-04 11:18:34

标签: java android android-camera crop

我有一个自定义相机应用程序,它有一个居中的矩形视图,如下所示:

Camera Screenshot

当我拍照时,我想忽略矩形之外的所有内容。该视图与我的XML视图中的Camera Preview或SurfaceView没有任何关联,如下所示:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
    android:id="@+id/preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SurfaceView
        android:id="@+id/cameraview"
        android:name="com.kut.camera.KutCameraFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <View android:id="@+id/viewTamanho"
        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" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:alpha="1"
            android:background="@android:color/black"
            android:orientation="vertical"
            android:padding="10dp" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <TextView
                    android:id="@+id/textViewReferan"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:layout_centerVertical="true"
                    android:text="Evidência"
                    android:textColor="@android:color/white"
                    android:textSize="16sp" />

                <Button
                    android:id="@+id/button_exit"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentEnd="true"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentTop="true"
                    android:background="@android:color/transparent"
                    android:text="Sair"
                    android:textColor="#2799CF" />
            </RelativeLayout>

            <LinearLayout
                android:id="@+id/progress_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:gravity="center"
                android:orientation="vertical"
                android:visibility="gone" >

                <ProgressBar
                    android:id="@+id/progressBar1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/islem_value_textView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Carregando..." />

            </LinearLayout>
        </LinearLayout>

        <RelativeLayout
            android:id="@+id/RelativeLayout1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:alpha="0.9"
            android:background="@android:color/black"
            android:padding="10dp" >

            <ImageView
                android:id="@+id/imageView_foto"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:src="@drawable/camera" />

            <ImageView
                android:id="@+id/imageView_photo"
                android:layout_width="80dp"
                android:layout_height="100dp"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="5dp"
                android:layout_marginEnd="5dp"
                android:padding="5dp"
                android:scaleType="fitCenter"
                android:src="@drawable/fotoicon" />
        </RelativeLayout>
    </RelativeLayout>
</FrameLayout>

有人可以帮助我正确裁剪图像吗?我尝试根据我的XML创建一个新的Bitmap,但显然它不起作用,如:

Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        //.../
        Bitmap imagemOriginal = BitmapFactory.decodeByteArray(data, 0, data.length);
        Bitmap imagemCortada = Bitmap.createBitmap(imagemOriginal, 70, 400, imagemOriginal.getWidth() - 70,
                imagemOriginal.getHeight() - 400);
        //.../
    }

我为x和y设置了这些初始值,并尝试从宽度和高度减去(基于来自ViewTom,Bottom等的视图中的XML值)但是我没有成功,因为我没有知道如何匹配View坐标和从Camera获取的图像坐标。另外,对我来说似乎Bitmap.createBitmap确实有限的裁剪,显然我不能直接将它裁剪成矩形。

2 个答案:

答案 0 :(得分:7)

要控制裁剪,您必须控制图片大小和矩形大小。

a)选择与预览具有相同宽高比的图片尺寸非常重要, b)确保预览不会在屏幕上失真。如果您为各种设备准备应用程序,则这两项任务都不是一件容易的事。要实现后者,您需要同时控制预览大小和 SurfaceView 大小。我已经更详细地解释了这一点elsewhere

为了简单起见,我建议忽略可能具有自然横向方向的平板电脑。在手机上,即使您将相机方向设置为纵向(仅影响预览),捕获的图像也将“旋转”90°。不要指望setRotation()为您解决这个问题:通过本书,可以简单地为捕获的图像设置EXIF标记。

您可以在 px 中设置 viewTamanho 的边距。这可能无法在各种屏幕上很好地扩展。我建议以编程方式设置此视图的尺寸,作为预览曲面的特定百分比。您可以使用support library在XML中定义它,但我担心这不会给您足够的控制权。

有了这一切,让我们说我们预览了1280×720,图片为2560×1440,我们的屏幕是1280×800,矩形在中间,616×400像素(更多或减去屏幕截图缩放的尺寸。

屏幕上的实际预览尺寸可能是1000x562,左右填充,黑色边距为79px。然后,以下代码将生成预期的捕获图片:

public void onPictureTaken(byte[] data, Camera camera) {
    //.../
    Bitmap imagemOriginal = BitmapFactory.decodeByteArray(data, 0, data.length); // 2560×1440
    float scale = 1280/1000F;
    int left = (int) scale*(imagemOriginal.getWidth()-400)/2;
    int top = (int) scale*(imagemOriginal.getHeight()-616)/2;
    int width = (int) scale*400;
    int height = (int) scale*616;
    Matrix rotationMatrix = new Matrix();
    rotationMatrix.postRotate(90);
    Bitmap imagemCortada = Bitmap.createBitmap(imagemOriginal, left, top, width, height, rotationMatrix, false);
    //.../
}

答案 1 :(得分:0)

enter image description here

这里我用过这个

implementation 'com.otaliastudios:cameraview:2.6.2'

拍照后获取位图图像的库。

这是我如何实现这一点的代码

public void croppingRectangle (Bitmap bitmap, CameraView mCameraView, FrameLayout rectangle) {

int cameraHeight = mCameraView.getHeight();
int cameraWidth = mCameraView.getWidth();

    DisplayMetrics displayMetrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

    int leftAndRightMarginsInPixels = Math.round(Math.round(getResources().getDimension(Your_dimens) * 2));`

在这里我做了缩放,拍照后

    int left = (int) Math.round(((double)rectangle.getX()/(double)cameraWidth) * bitmap.getWidth();
    int top = (int) Math.round(((double)rectangle.getY()/(double)cameraHeight) * bitmap.getHeight();
    int width =
            (int) (capturedWidth - Math.round(((double)leftAndRightMarginsInPixels / (double) displayMetrics.widthPixels) * bitmap.getWidth())); 
    int height = (int) Math.round(((double) rectangle.getHeight() / (double) displayMetrics.heightPixels) * bitmap.getHeight());

    Matrix rotationMatrix = new Matrix();
    rotationMatrix.postRotate(0);
    Bitmap croppedImage = Bitmap.createBitmap(bitmap, left, top, width, height, rotationMatrix, false);
}

P.S : 我已经实现了 95% 的顶部和底部的准确率,70% 的帧宽度