Android:将画布绘制到ImageView

时间:2011-02-07 04:31:40

标签: android imageview android-canvas draw

我是Android编程的新手,我想弄清楚的是这个;

在我的布局中,我有一个TextView,ImageView和Button,所有这些都在垂直方向的LinearLayout上。

我希望能够在ImageView中动态绘制圆圈,而不会干扰我的其余布局(textview / button)。我正在尝试创建一个画布,并使用画布中的drawcircle函数来设置圆的位置。然后以某种方式将该画布绘制到我的imageview。我不能让这个工作,这有什么诀窍吗?或者我的方法根本错了?如何在不重新创建整个布局的情况下将图形绘制到ImageView?

谢谢!

5 个答案:

答案 0 :(得分:31)

我遇到了同样的挑战并得出结论,覆盖onDraw至少在一般情况下不起作用。 My blog解释了原因。对我来说非常有效的是:

  1. 创建一个新的图像位图并为其附加一个全新的画布。
  2. 将图像位图绘制到画布中。
  3. 将您想要的所有其他内容绘制到画布中。
  4. 将画布附加到ImageView。
  5. 以下是此代码段:

    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.graphics.drawable.BitmapDrawable;
    
    ImageView myImageView = ...
    Bitmap myBitmap = ...
    Paint myRectPaint = ...
    int x1 = ...
    int y1 = ...
    int x2 = ...
    int y2 = ...
    
    //Create a new image bitmap and attach a brand new canvas to it
    Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565);
    Canvas tempCanvas = new Canvas(tempBitmap);
    
    //Draw the image bitmap into the cavas
    tempCanvas.drawBitmap(myBitmap, 0, 0, null);
    
    //Draw everything else you want into the canvas, in this example a rectangle with rounded edges
    tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint);
    
    //Attach the canvas to the ImageView
    myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));
    

答案 1 :(得分:25)

     ImageView imageView=(ImageView) findViewById(R.id.image);
        Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);    
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        canvas.drawCircle(50, 50, 10, paint);
        imageView.setImageBitmap(bitmap);

答案 2 :(得分:5)

我认为更好的方法是创建自定义ImageView并覆盖onDraw方法。类似的东西:

public class CustomView extends ImageView {

public CustomView(Context context) {
    super(context);
}

public CustomView(Context context, AttributeSet attrst) {
    super(context, attrst);
}

public CustomView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

MyBitmapFactory bitMapFac = null;
public void setBitmapFactory(MyBitmapFactory bitMapFac)
{
    this.bitMapFac = bitMapFac;
}

@Override
public void onDraw(Canvas canvas) {

    canvas.drawColor(Color.TRANSPARENT);
    /*instantiate a bitmap and draw stuff here, it could well be another
    class which you systematically update via a different thread so that you can get a fresh updated
    bitmap from, that you desire to be updated onto the custom ImageView. 
   That will happen everytime onDraw has received a call i.e. something like:*/
    Bitmap myBitmap = bitMapFac.update(); //where update returns the most up  to date Bitmap
    //here you set the rectangles in which you want to draw the bitmap and pass the bitmap        
    canvas.drawBitmap(myBitMap, new Rect(0,0,400,400), new Rect(0,0,240,135) , null);
    super.onDraw(canvas);
    //you need to call postInvalidate so that the system knows that it  should redraw your custom ImageView
    this.postInvalidate();
}
}

最好实现一些逻辑,检查是否有通过update()方法获取的新位图,这样onDraw中的代码不会每次都执行并且会给系统带来开销。 / p>

然后在您需要的任何地方使用自定义视图。最简单的方法是直接在activity_layout.xml中声明它:

   <com.mycustomviews.CustomView
        android:id="@+id/customView"
        android:layout_centerInParent="true"
        android:layout_height="135dp"
        android:layout_width="240dp"
       android:background="@android:color/transparent"/>

然后使用以下命令访问代码,就像使用其他任何视图一样:

   customView = (CustomView) findViewById(R.id.customView);

答案 3 :(得分:0)

如果您的xml具有布局,并且所有元素都以垂直方向排列。

您可以通过在包中扩展类视图并覆盖其onDraw方法来实现您想要的结果。根据需要在其中绘制圆圈。

然后在布局中添加imageView而不是在xml布局中添加自己的视图。如下所示

&LT; LinearLayout&gt;

 < TextView> < /TextView>

  < Button> < /Button>

  <com.prac.MyView> </ com.prac.MyView>

&LT; /&的LinearLayout GT;

检查以下链接以获取2D图形。这是一个很棒的教程。
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
希望这有帮助:)

答案 4 :(得分:0)

有几种方法可以做你想要的,但是按照你描述的方式使用ImageView不是其中之一。一种可能性是让ImageView显示动画Drawable。然后,您可以专注于让Drawable实现绘制圆圈。另一种方法是每次想要更改图像时创建一个新的Bitmap,并将ImageView设置为显示新的Bitmap。但是,通常的做法是创建自定义View子类。 API Demos示例项目有一个自定义视图示例,您可以在Google上找到很多教程。