簡體   English   中英

如何從surfaceView獲取位圖?

[英]How can I get bitmap from surfaceView?

我想從自定義surfaceView捕獲位圖圖像。 我嘗試在 imageView 中設置位圖圖像。

但是, surfaceView保存任何內容。

這是我的安卓代碼:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    OurSurface ourSurface;
    FrameLayout surfaceLayout;
    ImageView layoutCaptured;
    Button capture;

    Bitmap bitmap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        layoutCaptured = (ImageView)findViewById(R.id.layoutCaptured);
        surfaceLayout = (FrameLayout)findViewById(R.id.surfaceLayout);
        capture = (Button)findViewById(R.id.capture);
        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                surfaceLayout.setDrawingCacheEnabled(true);
                surfaceLayout.buildDrawingCache(true);
                Bitmap bmp = Bitmap.createBitmap(surfaceLayout.getDrawingCache());

                surfaceLayout.setDrawingCacheEnabled(false);

                layoutCaptured.setImageBitmap(bmp);

                Log.d("MainActivity", "onClick -> setImageBitmap");
            }
        });

        ourSurface = new OurSurface(this);
        surfaceLayout.addView(ourSurface);

    }

    @Override
    protected void onResume() {
        super.onResume();
        ourSurface.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        ourSurface.pause();
    }

    public class OurSurface extends SurfaceView implements Runnable{
        public OurSurface(Context context) {
            super(context);
            init(context);
        }

        public OurSurface(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }

        Thread thread;
        SurfaceHolder holder;
        boolean isItOK;
        Canvas canvas;
        int x1,y1,x2,y2,x3,y3;
        Paint red, green, blue;

        public void init(Context context){
            holder = getHolder();

            red = new Paint(Paint.ANTI_ALIAS_FLAG);
            red.setColor(Color.RED);
            red.setStyle(Paint.Style.FILL);
            green = new Paint(Paint.ANTI_ALIAS_FLAG);
            green.setColor(Color.GREEN);
            green.setStyle(Paint.Style.FILL);
            blue = new Paint(Paint.ANTI_ALIAS_FLAG);
            blue.setColor(Color.BLUE);
            blue.setStyle(Paint.Style.FILL);
        }

        public void resume(){
            isItOK = true;
            thread = new Thread(this);
            thread.start();
        }

        public void pause(){
            isItOK = false;
            while(true){
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                thread = null;
                break;
            }
        }

        int width, height;
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            width = w;
            height = h;
            Log.d("onSizeChanged", "width #"+width+", height #"+height);
            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(bitmap);
        }

        int x1Sign = 1, y1Sign = 1, x2Sign = 1, y2Sign = 1, x3Sign = 1, y3Sign = 1;
        @Override
        public void run() {
            while(isItOK == true){
                if(!holder.getSurface().isValid()){
                    continue;
                }
                canvas = holder.lockCanvas();

                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

                if(x1 > width) { x1 = width; x1Sign = (-1)*x1Sign; }
                else if(x1 < 0) { x1 = 0; x1Sign = (-1)*x1Sign; }
                if(y1 > height) { y1 = height; y1Sign = (-1)*y1Sign; }
                else if(y1 < 0) { y1 = 0; y1Sign = (-1)*y1Sign; }

                if(x2 > width) { x2 = width; x2Sign = (-1)*x2Sign; }
                else if(x2 < 0) { x2 = 0; x2Sign = (-1)*x2Sign; }
                if(y2 > height) { y2 = height; y2Sign = (-1)*y2Sign; }
                else if(y2 < 0) { y2 = 0; y2Sign = (-1)*y2Sign; }

                if(x3 > width) { x3 = width; x3Sign = (-1)*x3Sign; }
                else if(x3 < 0) { x3 = 0; x3Sign = (-1)*x3Sign; }
                if(y3 > height) { y3 = height; y3Sign = (-1)*y3Sign; }
                else if(y3 < 0) { y3 = 0; y3Sign = (-1)*y3Sign; }



                x1 = x1 + 1*x1Sign;
                y1 = y1 + 3*y1Sign;

                x2 = x2 + 2*x2Sign;
                y2 = y2 + 2*y2Sign;

                x3 = x3 + 3*x3Sign;
                y3 = y3 + 1*y3Sign;

                canvas.drawCircle(x1, y1, 10, red);
                canvas.drawCircle(x2, y2, 10, green);
                canvas.drawCircle(x3, y3, 10, blue);

                holder.unlockCanvasAndPost(canvas);
            }
        }
    }

}

和,activity_main.xml 代碼。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:orientation="vertical"
    android:weightSum="2">


    <LinearLayout
        android:weightSum="5"
        android:orientation="vertical"
        android:id="@+id/mainLayout"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="fill_parent">

        <Button
            android:layout_weight="1"
            android:text="capture"
            android:id="@+id/capture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/layoutCaptured"
            android:layout_weight="4"
            android:layout_width="match_parent"
            android:layout_height="fill_parent">

        </ImageView>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/surfaceLayout"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="fill_parent">
    </FrameLayout>



</LinearLayout>

請告訴我。

看來,直接獲取 SurfaceView 的位圖是不可能的。

事實上,在某些情況下,應用處理器甚至無法訪問 SurfaceView 的顯示數據——它可能是硬件視頻管道的輸出,它通過專用視頻疊加與應用處理器的顯示輸出合成。 1

在您的情況下,可以將畫布繪制為位圖,通常的配方是2

  1. 使用Bitmap.createBitmap()創建正確大小的位圖
  2. 使用Canvas(Bitmap)構造函數創建一個指向此位圖的畫布實例
  3. 繪制到畫布
  4. 使用位圖

更新

經過一些研究,它“可以”通過這樣做來工作:

public Bitmap getBitmap() {
    setDrawingCacheEnabled(true);
    buildDrawingCache(true);
    final Bitmap bitmap = Bitmap.createBitmap( getDrawingCache() );
    setDrawingCacheEnabled(false);
    destroyDrawingCache();
    return bitmap;
}

一個關於它的項目,可以在這里找到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM