Android自定义相机

编程入门 行业动态 更新时间:2024-10-28 22:23:11
Android自定义相机 - 在矩形内裁剪图像(Android Custom Camera - Crop image inside Rectangle)

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

当我拍照时,我想忽略矩形之外的所有东西。 该视图与我的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上,并试图从宽度和高度中减去(基于来自View引用marginTop,Bottom等的XML值)但是我没有成功,因为我不知道如何match使用从Camera获取的图像坐标查看坐标。 另外,对我来说似乎Bitmap.createBitmap确实有限的裁剪,显然我不能直接裁剪为矩形。

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

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>

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

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.

最满意答案

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

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

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

可以px中设置viewTamanho的边距。 这可能无法在各种屏幕上很好地扩展。 我建议以编程方式设置此视图的尺寸,作为预览曲面的特定百分比。 您可以使用支持库在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); //.../ }

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

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.

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.

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.

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).

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

更多推荐

本文发布于:2023-04-28 08:24:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1330922.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   相机   Android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!