Android:将画布绘制到 ImageView

发布于 2024-10-16 13:52:47 字数 299 浏览 6 评论 0原文

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

在我的布局中,我有一个 TextView、ImageView 和 Button,它们都位于垂直方向的 LinearLayout 上。

我希望能够在 ImageView 中动态绘制圆圈,而不干扰布局的其余部分(文本视图/按钮)。我正在尝试创建一个画布,并使用画布中的drawcircle函数来设置圆的位置。然后以某种方式将该画布绘制到我的图像视图中。我无法让它工作,有什么技巧吗?或者我的方法根本上是错误的?我将如何在不重新创建整个布局的情况下在 ImageView 上绘制圆圈?

谢谢!

I'm new to android programming and what I'm trying to figure out is this;

In my layout i have a TextView, ImageView, and Button, all on a vertically oriented LinearLayout.

I want to be able to dynamically draw circles in the ImageView, without disturbing the rest of my layout(textview/button). I'm trying to create a canvas, and use the drawcircle function within canvas to set the location of the circle. And then draw that canvas to my imageview in some way. I cannot get this to work, is there a trick to this? Or is my method fundamentally wrong? How would i go about drawing circles to the ImageView without recreating my entire layout?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一枫情书 2024-10-23 13:52:47
     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);
     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);
少钕鈤記 2024-10-23 13:52:47

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

  1. 创建一个新的图像位图并为其附加一个全新的画布。
  2. 将图像位图绘制到画布中。
  3. 将您想要的其他所有内容绘制到画布上。
  4. 将画布附加到 ImageView。

这是一个代码片段:

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));

I had the same challenge and came to the conclusion that overwriting onDraw will at least in the general case not work. My blog explains the reasons. What worked very well for me is the following:

  1. Create a new image bitmap and attach a brand new canvas to it.
  2. Draw the image bitmap into the canvas.
  3. Draw everything else you want into the canvas.
  4. Attach the canvas to the ImageView.

Here is a code snippet for this:

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));
无人问我粥可暖 2024-10-23 13:52:47

我认为更好的方法是创建自定义 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 中的代码就不会每次都执行并给系统带来开销。

然后在任何需要的地方使用您的自定义视图。最简单的方法是直接在 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);

I think that a better approach would be to create a custom ImageView and Override the onDraw method. Something like:

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();
}
}

It would be a good idea to implement some logic that checks if there is a fresh bitmap to acquire via the update() method, so that the code inside onDraw won't execute every time and put overhead to the system.

And then use your custom view wherever you need it. The easiest way would be to declare it directly inside the activity_layout.xml as such:

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

And then access is in your code like any other view by using:

   customView = (CustomView) findViewById(R.id.customView);
一个人的旅程 2024-10-23 13:52:47

如果您有一个带有布局的 xml,其中所有元素都以垂直方向排列。

您可以通过在包中创建一个扩展类视图并重写其 onDraw 方法的类来实现您想要的目的。根据需要在其中绘制圆圈。

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

线性布局>

 < TextView> < /TextView>

  < Button> < /Button>

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

< /线性布局>

检查以下 2D 图形链接。这是一本非常值得阅读的教程。

http://organicandroid.blogspot.com /2010/08/starting-to-play-with-graphics.html

希望这有帮助:)

If you have a xml with layout with all your elements arranged in vertical orienttion.

You can achieve what you want by making a class in your package which extends Class View and override its onDraw method. draw circle in it as you want .

then instead of adding imageView in the layout add this your own view in the xml layout.like the following

< LinearLayout >

 < TextView> < /TextView>

  < Button> < /Button>

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

< /LinearLayout>

Check the following link for 2D graphics. Its a great tutorial to read.

http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html


Hope this help : )

我不是你的备胎 2024-10-23 13:52:47

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

There are a couple of ways to do what you want, but using an ImageView the way you describe isn't one of them. One possibility is to have the ImageView display an animated Drawable. You can then focus on having your Drawable implementation draw the circles. Another is to create a new Bitmap every time you want the image to change and set the ImageView to display the new Bitmap. The usual way of doing this, though, is to create a custom View subclass. The API Demos sample project has an example of a custom view, and you can find lots tutorials with Google.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文