2013-06-03 95 views
1

我正在嘗試使用canvas.clipPath()在約束圈內繪製位圖圖像,類似於APP演示中的剪切活動。問題是我的代碼只能在模擬器上正確呈現,當在實際的Samsung Galaxy Nexus 4.2上運行時,它看起來好像clipPath更像矩形剪輯。我完全難倒了!我創建了一個新的Path()並在我的視圖ctor中解碼位圖。有什麼建議麼?Canvas clipPath僅適用於Android模擬器

@Override 
protected void onDraw(Canvas canvas) { 
    Point point = getPoint(); 
    path.reset(); 
    canvas.clipPath(path); // makes the clip empty 
    path.addCircle(point.x, point.y, getScale() * 140, Path.Direction.CCW); 
    canvas.clipPath(path, Region.Op.REPLACE); 

    Point scaledSize = new Point((int) (bitmapSize.x * getScale()), (int) (bitmapSize.y * getScale())); 
    Point topLeft = new Point((point.x - (scaledSize.x/2)), (point.y - (scaledSize.y/2))); 
    canvas.drawBitmap(bitmap, null, new Rect(topLeft.x, topLeft.y, topLeft.x + scaledSize.x, topLeft.y + scaledSize.y), paint); 
} 

Galaxy Nexus的 GalaxyNexus

模擬器

Emulator

回答

2

clipPath不支持硬件加速。 您可以使用像這樣創建裁剪位圖:

Bitmap clippedBitmap = ... // Create same size bitmap as source 
Paint paint = new Paint(); 
Canvas canvas = new Canvas(clippedBitmap); 
paint.setColor(Color.RED); 
paint.setStyle(PAint.Style.FILL); 
paint.setFilterBitmap(true); 
canvas.drawCircle(cx, cy, radius, paint); 
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
canvas.drawBitmap(sourceBitmap, 0, 0, paint); 

這樣做一次,然後繪製剪裁的位圖,而不是源一個

+0

完美!這就像一個魅力!現在如果我想動畫剪輯,減少/增加我的圈子的大小?我是否需要爲每個剪輯創建新的位圖,或者是否可以重新使用位圖並關聯畫布,每次都從原始源重新繪製? – Cliff

+1

您可以使用一個位圖,繪製一個更小或更大的內圓,然後將源位圖中的遮罩區域複製到新位圖中。根據動畫階段,裁剪的位圖將具有更小或更大的透明區域。 – yoah

2

ClipPath不支持硬件加速。在主題不支持的繪圖操作下檢查下面的鏈接。

http://developer.android.com/guide/topics/graphics/hardware-accel.html#drawing-support

您可以使用下面的參考和修改繪製圓的paramters滿足您的需求。

public class MainActivity extends Activity 
{ 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    DrawingView dv = new DrawingView(this); 
    dv.setBackgroundColor(Color.RED); 
    setContentView(dv); 
} 

class DrawingView extends View{ 
Bitmap bitmap; 


public DrawingView(Context context) 
{ 
super(context); 
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sqaure); 
} 


@Override 
public void onDraw(Canvas canvas) 
{ 
Paint paint = new Paint(); 
//paint.setStyle(Paint.Style.FILL); 
// paint.setColor(Color.CYAN); 
canvas.drawBitmap(getclip(), 0, 0, paint);//originally x and y is o and o . 

} 
public Bitmap getclip() 
{ 
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), 
     bitmap.getHeight(), Config.ARGB_8888); 
Canvas canvas = new Canvas(output); 
final int color = 0xff424242; 
final Paint paint = new Paint(); 
final Rect rect = new Rect(0, 0, bitmap.getWidth(), 
     bitmap.getHeight()); 
paint.setColor(Color.RED); 
paint.setStyle(Paint.Style.FILL); 
paint.setAntiAlias(true); 
canvas.drawARGB(0, 0, 0, 0); 
//paint.setColor(color); 
canvas.drawCircle(bitmap.getWidth()/2-40, 
     bitmap.getHeight()/2, bitmap.getWidth()/2-40, paint); 
    // change the parameters accordin to your needs. 
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
canvas.drawBitmap(bitmap, rect, rect, paint); 
return output; 
    } 
    } 
} 

enter image description here

4

ClipPath不支持硬件加速

您可以關閉硬件加速使用本:

setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
+0

從哪個API開始工作很好?例如,我注意到可以不使用Android 4.4。 –

相關問題