Android自定义相机-在矩形内裁剪图像 [英] Android Custom Camera - Crop image inside Rectangle

查看:88
本文介绍了Android自定义相机-在矩形内裁剪图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a custom camera app which have a centered rectangle view, as you can see below:

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

When I take a picture I want to ignore everything outside the rectangle. The view hasn't any connection with the Camera Preview or SurfaceView in my XML view, as follows:

<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创建一个新的位图,但显然不起作用,就像这样:

Can somebody help me how to crop the image properly? I tried to create a new Bitmap based on my XML but obviously it didn't work, something like:

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的初始值,并尝试从width和Height中减去(基于View的XML值,该值指的是marginTop,Bottom等),但是我没有成功,因为我没有知道如何将View坐标与从Camera拍摄的图像坐标相匹配.另外,对我而言,Bitmap.createBitmap似乎限制了裁剪,显然我无法直接将其裁剪为矩形.

I put those initial values for x and y, and tried to subtract (based on XML values from View referring to marginTop, Bottom, etc...) from width and Height but I hadn't success because I don't know how to match View coordinates with the image coordinates taken from Camera. Also, it seems for me Bitmap.createBitmap does limited crop, apparently I can't crop it to a rectangle directly.

推荐答案

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

To control cropping, you must control the picture size and the rectangle size.

a)选择与预览相同的长宽比的图片尺寸非常重要,并且 b)确保预览不会在屏幕上变形. .如果您为各种设备准备应用程序,那么两项任务都不是简单的.要实现后者,您需要控制预览大小和 SurfaceView 大小.我已经详细说明了

It is very important to a) choose the picture size with same aspect ratio as the preview, and b) make sure that the preview is not distorted on the screen. If you prepare your app for a wide range of devices, both tasks are not trivial. To achieve the latter, you need to control both preview size and the SurfaceView size. I have explained this in more detail elsewhere.

为简单起见,我建议忽略可能具有自然风景"取向的平板电脑.在手机上,捕获的图像将旋转" 90度.即使您将相机方向设置为纵向(仅效果预览)也是如此.不要期望 setRotation()到为您解决此问题:按照书的规定,只需为捕获的图像设置EXIF标志即可.

To keep it simple, I suggest to ignore the tablets that may have natural Landscape orientation. On phones, the captured image will be "rotated" 90° even if you set camera orientation to portrait (which only effects preview). Don't expect setRotation() to fix this for you: by the book, it is allowed to simply set the EXIF flag for the captured image.

您以 px 设置 viewTamanho 的边距.这可能无法在各种屏幕上很好地缩放.我建议以编程方式将此视图的尺寸设置为预览表面的一定百分比.您可以使用支持库在XML中进行定义,但我恐怕这不会给您足够的控制权.

You set the margins for viewTamanho in px. This may not scale well on variety of screens. I suggest setting the dimensions of this view programmatically, as certain percent of the preview surface. You can use support library to define this in XML, but I am afraid this will not give you enough control.

有了这些,我们假设预览为1280×720,图片为2560×1440,屏幕为1280×800,矩形位于中间,为616×400像素(减去屏幕截图中缩放的尺寸.

With all this at hand, let's say that we have preview of 1280×720, picture of 2560×1440, our screen is 1280×800, and the rectangle is in the middle, 616×400 pixels (which is more or less the size scaled from your screenshot).

屏幕上的实际预览大小可能为1000x562,左右两侧分别填充79px的黑色边距.然后,以下代码将生成预期的捕获图片:

The actual preview size on screen will be probably 1000x562, padded on the right and left with black margins of 79px. Then the following code will produce the expected captured picture:

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);
    //.../
}

这篇关于Android自定义相机-在矩形内裁剪图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆