web-dev-qa-db-ja.com

Androidカスタムカメラ-長方形内の画像を切り抜く

以下に示すように、中央に長方形のビューがあるカスタムカメラアプリがあります。

Camera Screenshot

写真を撮るときは、長方形の外側をすべて無視したいと思います。次のように、ビューはXMLビューのCameraPreviewまたは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に基づいて新しいビットマップを作成しようとしましたが、明らかに機能しませんでした。次のようになります。

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の初期値を入力し、幅と高さから(marginTop、Bottomなどを参照するViewのXML値に基づいて)減算しようとしましたが、方法がわからないため成功しませんでした。ビュー座標をカメラから取得した画像座標と一致させます。また、私にはBitmap.createBitmapのトリミングが制限されているようですが、長方形に直接トリミングすることはできないようです。

7
bl4ck code

トリミングを制御するには、画像サイズと長方形サイズを制御する必要があります。

a)プレビューと同じアスペクト比の画像サイズを選択することが非常に重要です。b)プレビューは画面上で歪んでいません。さまざまなデバイス向けにアプリを準備する場合、両方のタスクは簡単ではありません。後者を実現するには、プレビューサイズとSurfaceViewサイズの両方を制御する必要があります。私はこれをより詳細に説明しました 他の場所

簡単にするために、自然の風景の向きを持つ可能性のあるタブレットは無視することをお勧めします。携帯電話では、カメラの向きをポートレートに設定した場合でも、キャプチャされた画像は90°「回転」します(これはプレビューにのみ影響します)。 setRotation() がこれを修正することを期待しないでください。本では、キャプチャされた画像にEXIFフラグを設定するだけで済みます。

pxviewTamanhoのマージンを設定します。これは、さまざまな画面で適切にスケーリングされない場合があります。プレビューサーフェスの特定のパーセントとして、このビューのサイズをプログラムで設定することをお勧めします。 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);
    //.../
}
8
Alex Cohn