【问题标题】:How to make any view to draw to canvas?如何使任何视图绘制到画布上?
【发布时间】:2013-07-06 02:14:44
【问题描述】:

我有一个简短的问题:

假设我有一个(可变)位图需要修改(添加图像、文本等)。

与其搞乱许多用于在画布上绘制的特殊类(绘画、画布、矩阵等),我在想为什么不使用 Android 的内置类来完成这项任务,并且只有当我需要真正定制的操作时我还能用画布吗?

因此,例如,为了在位图上显示任何类型的视图(当然没有父视图),我可以调用下一个函数:

public void drawViewToBitmap(Bitmap b, View v, Rect rect) {
    Canvas c = new Canvas(b);
    // <= use rect to let the view to draw only into this boundary inside the bitmap
    view.draw(c);
}

这样的事情可能吗?也许这就是它在幕后工作的方式?

在绘图和画布创建之间的部分我应该写什么?


编辑:我已经尝试了下一个代码,但它没有工作:

public void drawFromViewToCanvas(final View view, final Rect rect, final Canvas canvas) {
    final int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
    final int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
    view.measure(widthSpec, heightSpec);
    // Lay the view out with the known dimensions
    view.layout(0, 0, rect.width(), rect.height());
    // Translate the canvas so the view is drawn at the proper coordinates
    canvas.save();
    canvas.translate(rect.left, rect.top);
    // Draw the View and clear the translation
    view.draw(canvas);
    canvas.restore();
}

使用示例:

final int imageSize = 50;
rect = new Rect(35, 344 , 35 + imageSize, 344  + imageSize);
final ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ScaleType.CENTER_CROP);
drawFromViewToCanvas(imageView, getRect(), canvas);

编辑:sony's website 上有一个示例:

int measureWidth = View.MeasureSpec.makeMeasureSpec(bitmapWidth, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(bitmapHeight, View.MeasureSpec.EXACTLY);
view.measure(measureWidth, measuredHeight);
view.layout(0, 0, bitmapWidth, bitmapHeight);
view.draw(canvas);

想知道它是否有效。

【问题讨论】:

    标签: android bitmap draw android-canvas mutable


    【解决方案1】:

    是的,你可以这样做。请记住,由于您没有将其附加到布局,因此您需要在绘制之前手动布局:

    view.layout(0, 0, viewWidth, viewHeight);
    

    除非你确切地知道你想要的那些宽度和高度参数,否则你可能还想先测量它:

    int widthSpec = MeasureSpec.makeMeasureSpec (ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED;
    int heightSpec = MeasureSpec.makeMeasureSpec (400, MeasureSpec.UNSPECIFIED;
    view.measure(widthSpec, heightSpec);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    

    编辑:

    如果您已经知道所需的宽度和高度:

    //Lay the view out with the known dimensions
    view.layout (0, 0, rect.width(), rect.height());
    
    //Translate the canvas so the view is drawn at the proper coordinates
    canvas.save();
    canvas.translate(rect.left, rect.top);
    
    //Draw the View and clear the translation
    view.draw(canvas);
    canvas.restore();
    

    再次编辑:

    是的,经过测试。你可以自己试试:

    public class DrawingActivity extends Activity {
        public void onCreate (Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            //Set a Rect for the 200 x 200 px center of a 400 x 400 px area
            Rect rect = new Rect();
            rect.set(100, 100, 300, 300);
    
            //Allocate a new Bitmap at 400 x 400 px
            Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
    
            //Make a new view and lay it out at the desired Rect dimensions
            TextView view = new TextView(this);
            view.setText("This is a custom drawn textview");
            view.setBackgroundColor(Color.RED);
            view.setGravity(Gravity.CENTER);
    
            //Measure the view at the exact dimensions (otherwise the text won't center correctly)
            int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
            int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
            view.measure(widthSpec, heightSpec);
    
            //Lay the view out at the rect width and height
            view.layout(0, 0, rect.width(), rect.height());
    
            //Translate the Canvas into position and draw it
            canvas.save();
            canvas.translate(rect.left, rect.top);
            view.draw(canvas);
            canvas.restore();
    
            //To make sure it works, set the bitmap to an ImageView
            ImageView imageView = new ImageView(this);
            imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            setContentView(imageView);
            imageView.setScaleType(ImageView.ScaleType.CENTER);
            imageView.setImageBitmap(bitmap);
        }
    }
    

    【讨论】:

    • 我提到的矩形应该用于允许视图绘制的宽度和高度。我可以使用它的宽度和高度吗?另外,绘制到矩形位置的部分在哪里?
    • 如果你已经知道位置和大小,那就简单多了。查看编辑。
    • 你确定它有效吗?你试过吗,例如,在 textView 或 imageView 上?
    • 酷。将很快对其进行测试并在之后标记此答案。谢谢!您是否也可以查看这个非常相似的问题:stackoverflow.com/questions/17189809/…,或者可能完全相同?
    • 对我来说听起来是同一个问题。
    猜你喜欢
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    相关资源
    最近更新 更多