2015-10-14 110 views
1

我想從自定義surfaceView中捕獲位圖圖像。 我試圖在imageView中設置BitmapImage。如何從surfaceView獲取位圖?

但是,surfaceView不保存任何東西。

這裏是我的Android代碼:

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> 

請讓我知道。

+0

[Android截圖表面視圖顯示黑屏]的可能重複(http://stackoverflow.com/questions/27817577/android-take-screenshot-of-surface-view-shows-black-screen) – fadden

回答

0

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

事實上,存在這樣的情況,其中用於SurfaceView 顯示數據不是連到應用處理器訪問 - 它可以是 硬件視頻管線,其與合成的 顯示輸出的輸出應用處理器通過專用視頻覆蓋。 1

你的情況有可能在畫布上繪製一個位圖,通常的配方是2

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

UPDATE

經過一番研究,它 「可能」 是通過做這項工作:

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

關於它的項目,可以發現here