2015-12-28 19 views
1

我正在創建android應用程序,我需要從包含imageview的框架佈局中獲取位圖,其次是自定義表面視圖xml文件如下,但是當我嘗試使屏幕從框架佈局短我得到下面只圖像不是上面影像的位圖可以在任何一個高大的我,我怎麼能得到所有FRAM佈局在android中我怎樣才能從自定義表面視圖獲取屏幕截圖或位圖

<LinearLayout 
    android:id="@+id/linear" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center|center_horizontal" 
    android:layout_marginLeft="20dp" 
    android:layout_marginRight="20dp" 
    android:layout_marginTop="10dp" 
    android:orientation="horizontal" > 

    <FrameLayout 
     android:id="@+id/frame" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" > 

     <FrameLayout 
      android:id="@+id/frmQueue" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" > 

      <ImageView 
       android:id="@+id/imglow" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:contentDescription="@string/app_name" 
       android:scaleType="centerCrop" /> 

      <com.winsontan520.WScratchView 
      android:id="@+id/scratch_view" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center"/> 

     </FrameLayout> 
    </FrameLayout> 
</LinearLayout> 

WScratchView.java

public class WScratchView extends SurfaceView implements IWScratchView, SurfaceHolder.Callback { 
private static final String TAG = "WScratchView"; 

// default value constants 
private final int DEFAULT_COLOR = 0xff444444; // default color is dark gray 
public static int DEFAULT_REVEAL_SIZE = 30; 

public static final int DEFAULT_SCRATCH_TEST_SPEED = 4; 
private Context mContext; 
public Bitmap mbits; 
private WScratchViewThread mThread; 
List<Path> mPathList = new ArrayList<Path>(); 
public int mOverlayColor; 
public Paint mOverlayPaint; 
public int mRevealSize; 
private boolean mIsScratchable = true; 
private boolean mIsAntiAlias = false; 
private Path path; 
private float startX = 0; 
private float startY = 0; 
private boolean mScratchStart = false; 
public Bitmap mScratchBitmap; 
public Drawable mScratchDrawable = null; 
private Paint mBitmapPaint; 
private Matrix mMatrix; 
private Bitmap mScratchedTestBitmap; 
public Canvas mScratchedTestCanvas; 
private OnScratchCallback mOnScratchCallback; 

//Enable scratch all area if mClearCanvas is true 
private boolean mClearCanvas = false; 
//Enable click on WScratchView if mIsClickable is true 
private boolean mIsClickable = false; 

public WScratchView(Context ctx, AttributeSet attrs) { 
    super(ctx, attrs); 
    init(ctx, attrs); 
} 

public WScratchView(Context context) { 
    super(context); 
    init(context, null); 
} 

private void init(Context context, AttributeSet attrs) { 
    mContext = context; 

    // default value 
    mOverlayColor = DEFAULT_COLOR; 
    mRevealSize = DEFAULT_REVEAL_SIZE; 

    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WScratchView, 0, 0); 

    final int indexCount = ta.getIndexCount(); 
    for (int i = 0; i < indexCount; i++) { 
     int attr = ta.getIndex(i); 
     if (attr == R.styleable.WScratchView_overlayColor) { 
      mOverlayColor = ta.getColor(attr, DEFAULT_COLOR); 
     } else if (attr == R.styleable.WScratchView_revealSize) { 
      mRevealSize = ta.getDimensionPixelSize(attr, DEFAULT_REVEAL_SIZE); 
     } else if (attr == R.styleable.WScratchView_antiAlias) { 
      mIsAntiAlias = ta.getBoolean(attr, false); 
     } else if (attr == R.styleable.WScratchView_scratchable) { 
      mIsScratchable = ta.getBoolean(attr, true); 
     } else if (attr == R.styleable.WScratchView_scratchDrawable) { 
      mScratchDrawable = ta.getDrawable(R.styleable.WScratchView_scratchDrawable); 
     } 
    } 

    setZOrderOnTop(true); 
    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 
    holder.setFormat(PixelFormat.TRANSPARENT); 

    mOverlayPaint = new Paint(); 
    mOverlayPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); 
    mOverlayPaint.setStyle(Paint.Style.STROKE); 
    mOverlayPaint.setStrokeCap(Paint.Cap.ROUND); 
    mOverlayPaint.setStrokeJoin(Paint.Join.ROUND); 

    // convert drawable to bitmap if drawable already set in xml 
    if (mScratchDrawable != null) { 
     mScratchBitmap = ((BitmapDrawable) mScratchDrawable).getBitmap(); 
    } 

    mBitmapPaint = new Paint(); 
    mBitmapPaint.setAntiAlias(true); 
    mBitmapPaint.setFilterBitmap(true); 
    mBitmapPaint.setDither(true); 
} 

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    //Clear all area if mClearCanvas is true 
    if(mClearCanvas){ 
     canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
     return; 
    } 

    if (mScratchBitmap != null) { 
     if (mMatrix == null) { 
      float scaleWidth = (float) canvas.getWidth()/mScratchBitmap.getWidth(); 
      float scaleHeight = (float) canvas.getHeight()/mScratchBitmap.getHeight(); 
      mMatrix = new Matrix(); 
      mMatrix.postScale(scaleWidth, scaleHeight); 
     } 
     canvas.drawBitmap(mScratchBitmap, mMatrix, mBitmapPaint); 
    } else { 
     canvas.drawColor(mOverlayColor); 
    } 

    for (Path path : mPathList) { 
     mOverlayPaint.setAntiAlias(mIsAntiAlias); 
     mOverlayPaint.setStrokeWidth(mRevealSize); 

     canvas.drawPath(path, mOverlayPaint); 
    } 


} 

private void updateScratchedPercentage() { 
    if(mOnScratchCallback == null) return; 
    mOnScratchCallback.onScratch(getScratchedRatio()); 
} 

@Override 
public boolean onTouchEvent(MotionEvent me) { 
    synchronized (mThread.getSurfaceHolder()) { 
     if (!mIsScratchable) { 
      return true; 
     } 

     switch (me.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      path = new Path(); 
      path.moveTo(me.getX(), me.getY()); 
      startX = me.getX(); 
      startY = me.getY(); 
      mPathList.add(path); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if (mScratchStart) { 
       path.lineTo(me.getX(), me.getY()); 
      } else { 
       if (isScratch(startX, me.getX(), startY, me.getY())) { 
        mScratchStart = true; 
        path.lineTo(me.getX(), me.getY()); 
       } 
      } 
      updateScratchedPercentage(); 
      break; 
     case MotionEvent.ACTION_UP: 
      //Set call back if user's finger detach 
      if(mOnScratchCallback != null){ 
        mOnScratchCallback.onDetach(true); 
      } 
      //perform Click action if the motion is not move 
      //and the WScratchView is clickable 
      if(!mScratchStart && mIsClickable){ 
       post(new Runnable() { 
        @Override 
        public void run() { 
         performClick(); 
        } 
       }); 
      } 
      mScratchStart = false; 
      break; 
     } 
     return true; 
    } 
} 

private boolean isScratch(float oldX, float x, float oldY, float y) { 
    float distance = (float) Math.sqrt(Math.pow(oldX - x, 2) + Math.pow(oldY - y, 2)); 
    if (distance > mRevealSize * 2) { 
     return true; 
    } else { 
     return false; 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
    // do nothing 
} 

@Override 
public void surfaceCreated(SurfaceHolder arg0) { 
    mThread = new WScratchViewThread(getHolder(), this); 
    mThread.setRunning(true); 
    mThread.start(); 

    mScratchedTestBitmap = Bitmap.createBitmap(arg0.getSurfaceFrame().width(), arg0.getSurfaceFrame().height(), Bitmap.Config.ARGB_8888); 
    mScratchedTestCanvas = new Canvas(mScratchedTestBitmap); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder arg0) { 
    boolean retry = true; 
    mThread.setRunning(false); 
    while (retry) { 
     try { 
      mThread.join(); 
      retry = false; 
     } catch (InterruptedException e) { 
      // do nothing but keep retry 
     } 
    } 

} 

class WScratchViewThread extends Thread { 
    private SurfaceHolder mSurfaceHolder; 
    private WScratchView mView; 
    private boolean mRun = false; 

    public WScratchViewThread(SurfaceHolder surfaceHolder, WScratchView view) { 
     mSurfaceHolder = surfaceHolder; 
     mView = view; 
    } 

    public void setRunning(boolean run) { 
     mRun = run; 
    } 

    public SurfaceHolder getSurfaceHolder() { 
     return mSurfaceHolder; 
    } 

    @Override 
    public void run() { 
     Canvas c; 
     while (mRun) { 
      c = null; 
      try { 
       c = mSurfaceHolder.lockCanvas(null); 
       synchronized (mSurfaceHolder) { 
        if (c != null) { 
         mView.draw(c); 
        } 
       } 
      } finally { 
       if (c != null) { 
        mSurfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
     } 
    } 
} 

@Override 
public void resetView() { 
    synchronized (mThread.getSurfaceHolder()) { 
     mPathList.clear(); 
    } 
} 

@Override 
public boolean isScratchable() 
{ 
    return mIsScratchable; 
} 

@Override 
public void setScratchable(boolean flag) { 
    mIsScratchable = flag; 
} 

@Override 
public void setOverlayColor(int ResId) { 
    mOverlayColor = ResId; 
} 

@Override 
public void setRevealSize(int size) { 
    mRevealSize = size; 
} 

@Override 
public void setAntiAlias(boolean flag) { 
    mIsAntiAlias = flag; 
} 


@Override 
public void setScratchDrawable(Drawable d) { 
    mScratchDrawable = d; 
    if (mScratchDrawable != null) { 
     mScratchBitmap = ((BitmapDrawable) mScratchDrawable).getBitmap(); 
    } 
} 

@Override 
public void setScratchBitmap(Bitmap b) { 
    mScratchBitmap = b; 
} 


@Override 
public float getScratchedRatio() { 
    return getScratchedRatio(DEFAULT_SCRATCH_TEST_SPEED); 
} 

/** 
* thanks to https://github.com/daveyfong for providing this method 
*/ 
@Override 
public float getScratchedRatio(int speed) { 
    if (null == mScratchedTestBitmap) { 
     return 0; 
    } 
    draw(mScratchedTestCanvas); 

    final int width = mScratchedTestBitmap.getWidth(); 
    final int height = mScratchedTestBitmap.getHeight(); 

    int count = 0; 
    for (int i = 0; i < width; i += speed) { 
     for (int j = 0; j < height; j += speed) { 
      if (0 == Color.alpha(mScratchedTestBitmap.getPixel(i, j))) { 
       count++; 
      } 
     } 
    } 
    float completed = (float) count/((width/speed) * (height/speed)) * 100; 

    return completed; 
} 

@Override 
public void setOnScratchCallback(OnScratchCallback callback) { 
    mOnScratchCallback = callback; 
} 

public static abstract class OnScratchCallback{ 
    public abstract void onScratch(float percentage); 
    //Call back funtion to monitor the status of finger 
    public abstract void onDetach(boolean fingerDetach); 
} 

//Set the mClearCanvas 
@Override 
public void setScratchAll(boolean scratchAll){ 
    mClearCanvas = scratchAll; 
} 

//Set the WScartchView clickable 
@Override 
public void setBackgroundClickable(boolean clickable){ 
    mIsClickable = clickable; 
} 
的位圖

}

和位圖的代碼如下

gray.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View arg0) { 
      // TODO Auto-generated method stub 
      FrameLayout fm = (FrameLayout)findViewById(R.id.frmQueue); 
      fm.setDrawingCacheEnabled(true); 
      fm.buildDrawingCache(); 
      Bitmap bm =fm.getDrawingCache(); 

      scratchView.setScratchBitmap(bm); 

回答

0

你可以試試這個代碼段

public Bitmap loadBitmapFromView(View v, int width, int height) { 
    Bitmap b = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888); 
    Canvas c = new Canvas(b); 
    v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height); 
    v.draw(c); 
    return b; 
} 

調用會是這樣的

Bitmap imageBitmap = loadBitmapFromView(frameLayout, frameLayout.getLayoutParams().width,frameLayout.getLayoutParams().height)); 

您可以使用此代碼爲FrameLayout?

FrameLayout view = (FrameLayout)findViewById(R.id.framelayout); 
    view.setDrawingCacheEnabled(true); 
    view.buildDrawingCache(); 
    Bitmap bm = view.getDrawingCache(); 
+0

我試過這一個,但它仍然給我只有圖像低位圖。我沒有從scratch_image獲取位圖 –

+0

你現在能夠解決這個問題嗎? – sector11

+0

我想從framlayout獲得整個位圖,但我仍然無法做到 –