为什么我不能将较小的位图绘制到更大的画布中?

时间:2012-04-06 21:17:22

标签: android canvas

我创建了一个自定义视图(显示),它接受创建半静态(很少变化)位图的非视图图标。我们的想法是将大量图标传递给显示器以打印到其画布上。我的问题是我无法让Display实际将Icons位图绘制到其画布中。

下面的代码是我所拥有的一个工作示例。 (通过工作我的意思是正确执行,而不是打印出我想要的东西)

public class AndroidTestoActivity extends Activity {
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout fl = new FrameLayout(this);
        Display tv = new Display(this); 
        tv.setLayoutParams(new LayoutParams(200, 200));
        fl.addView(tv);
        setContentView(fl);
    }

    public class Display extends View {
        Paint vPaint = new Paint();
        Icon item = new Icon();

        public Display(Context context) {
            super(context);
            vPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            vPaint.setColor(0x0ff000000);
            setBackgroundColor(0xffffffff);
        }

        @Override public void onDraw(Canvas canvas) {
            canvas.scale(200, 200);
            item.onDraw(canvas);
            canvas.drawLine(0.0f, 0.0f, 1.0f, 1.0f, vPaint);
        }
    }

    public class Icon {
        Bitmap myImage;
        Paint mPaint = new Paint();

        public Icon() {
            myImage = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
            mPaint.setStyle(Style.FILL);
            mPaint.setColor(0xffff0000);
            Canvas c = new Canvas(myImage);
            c.scale(50, 50);
            c.drawCircle(0.5f, 0.5f, 0.5f, mPaint);
        }

        public void onDraw(Canvas canvas) {
            canvas.drawBitmap(myImage, 0, 0, null);
        }
    }
}

此代码应从左上角到右下角打印出一条直线,并从0,0到50,50绘制一个直径为50px的圆圈。相反,我得到的就是直线。但是,如果我将位图打印到文件,该文件将完全输出它应该输出的内容。

有没有人知道发生了什么?

修改
为了澄清我的问题,我创建了一个比DisplayView小得多的Bitmap。当我尝试将位图绘制到DisplayView中时,位图根本不是我绘制的,并且从未适当缩放。为什么画布没有正确绘制位图?

更新
在Diplay的onDraw方法中,我将行items.onDraw(canvas);移到canvas.scale(200, 200);之前。现在测试圆正确绘制。什么是如此简单的改变,完全忽略了以某种方式绘制圆圈?

4 个答案:

答案 0 :(得分:1)

事实证明,我@MartinAsenov大多是正确的。我最终需要做的是在之前绘制所有缓存的位图(或者在保存和恢复之后)我缩放画布并正常绘制。至于缩放画布,我相信这仍然是必要的(在绘制之前,我的所有其他小部件都会缩放到它们的宽度和高度)。

这是最终的工作测试活动。

public class AndroidTestoActivity extends Activity {
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout fl = new FrameLayout(this);
        Display tv = new Display(this); 
        tv.setLayoutParams(new LayoutParams(200, 200));
        fl.addView(tv);
        setContentView(fl);
    }

    public class Display extends View {
        Paint vPaint = new Paint();
        Icon item = new Icon();

        public Display(Context context) {
            super(context);
            vPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            vPaint.setColor(0x0ff000000);
            setBackgroundColor(0xffffffff);
        }

        @Override public void onDraw(Canvas canvas) {
            item.onDraw(canvas);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.scale(getWidth(), getHeight());

            canvas.drawLine(0.0f, 0.0f, 1.0f, 1.0f, vPaint);
            canvas.restore();
        }
    }

    public class Icon {
        Bitmap myImage;
        Paint mPaint = new Paint();

        public Icon() {
            myImage = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
            mPaint.setStyle(Style.FILL);
            mPaint.setColor(0xffff0000);
            Canvas c = new Canvas(myImage);
            c.scale(50, 50);
            c.drawCircle(0.5f, 0.5f, 0.5f, mPaint);
        }

        public void onDraw(Canvas canvas) {
            canvas.drawBitmap(myImage, 50, 50, null);
        }
    }
}

答案 1 :(得分:0)

查看你的代码我认为主要的问题是你假设坐标为0f..1f,但事实是0f..width / 0f..height - float用于有子像素

答案 2 :(得分:0)

我最好的猜测是圆圈变得太大(缩放200倍),因此其坐标变为负值(即左上角为(-5,-10))。 android系统不会使用负坐标绘制视图(如果你想实现这一点,你需要覆盖onMeasure()方法)

答案 3 :(得分:0)

我认为你对画布的工作方式有点混淆(而且它不直观,所以很容易混淆)。你调用Canvas的方式,将Bitmap作为一个参数,它最终将位图视为被绘制的东西,因此,你受到位图尺寸的限制。 如果您要创建一个没有param(一个空画布)的Canvas,然后将一个位图绘制到其中,那么它实际上不会改变Bitmap,它只是在画布上绘制。在这种情况下,您可以在矩形内的任何位置绘制位图,并在其周围绘制一个圆圈(或任何您想要的其他内容)。

此外,你可以覆盖onDraw方法并收集*它的画布(当它调用回调时它会把它给你),然后你可以在画布上绘制任何你想要的东西......那就是实际显示在屏幕上的画布,这是访问它的最简单方法。