我正在开发一个应用程序,该应用程序在 imageview 中显示大(大约 2000x2000px)位图。该图像必须那么大,因为用户可以通过捏合来缩放它以查看一些细节。应用程序必须能够在该图像上绘制圆圈,并且还必须能够单独显示图像,而没有圆圈。我使用的是 2 层,但问题是内存,因为 2k x 2k px 大约是 16mb 的内存,并且创建另一个位图(另一个 16mb)只是为了画几个圆圈,在我看来是没有意义的。有什么方法可以在图像上绘制简单的图元,并且还可以在没有图元的情况下显示它(在我的例子中是圆圈)?也许以某种方式只存储修改后的像素或某事?谢谢!
2 回答
您不需要再制作 2000x2000Bitmap
来绘制这些圆圈。只需“预渲染”一个圆圈,然后选择绘制它的位置。
我正在假设您在 a 上绘制“大”图像Canvas
,因为您具有缩放功能等。
如果不是,则需要覆盖 SurfaceView 的onDraw(Canvas canvas)
方法,以便可以访问SurfaceView Canvas
. 我不会深入讨论该部分,因为我再次假设您拥有它,但如果没有,该函数的实现将如下所示:
//Overriding SurfaceView onDraw(Canvas canvas)
@Override
protected void onDraw(Canvas surfaceCanvas) {
if(canvas == null) return; //No Canvas? No point in drawing then.
surfaceCanvas.drawColor(Color.BLACK);
//Draw your 'big' image on the SurfaceView Canvas
insertYourBigImageDrawingFunctionHere(surfaceCanvas);
//Now draw your circles at their correct positions...
insertCircleDrawingFunctionHere(surfaceCanvas);
}
现在您可以访问 SurfaceView 画布,您可以精确地选择在其上绘制事物的方式。比如圆圈……
我想提请您注意Canvas
下面使用的多个 '(surfaceCanvas 与 circleCanvas)。我曾经认为 Canvas 是一种“用于整个应用程序/活动的 Canvas”实现,但事实并非如此。您可以随意创建Canvas
'。它只是在位图上绘制的工具的一个实例。这对我来说是一个巨大的启示,让我对位图的组成方式有了更强大的控制。
public void myCircleDrawingFunction(Canvas surfaceCanvas){
//Make a new Bitmap for your circle
Bitmap.Config conf = Bitmap.Config.ARGB_4444;
tinyCircleBMP = Bitmap.createBitmap(10,10, conf);
//Make a new canvas using that Bitmap as the source...
Canvas circleCanvas = new Canvas(cacheBmp);
//Now, perform your drawing on the `Canvas`...
Paint p = new Paint();
circleCanvas.drawCircle(5, 5, 5, p);
//Now the `Bitmap` has a circle on it, draw the `Bitmap` on the `SufaceView Canvas`
surfaceCanvas.drawBitmap(tinyCircleBMP, 10, 10, p);
//Replace the '10's in the above function with relevant coordinates.
}
现在很明显,您的圆圈将与您的“大”图像不同地缩放/平移,因为它们不再以“大”图像的相同大小/位置绘制。您将需要考虑如何在考虑“大”图像的当前比例和位置的情况下转换每个圆圈的位置。
例如,如果您的图像放大到 200%,并且应该在距离大图像左侧 100px 处出现一个圆圈,那么您应该乘以像素值以考虑缩放,像这样
(伪代码):
drawCircleAtX = Bitmap.left * BitmapZoomFactor
如果您使用的是 canvas API(如果不是,我会建议)?如果是这样,您只需在画布上绘制图像,然后在显示之前在同一画布上绘制原始形状。这样,您只需保留一些基本数据类型中圆圈位置的参考,并在用户四处移动和缩放时对其进行缩放,这样您就知道每帧在哪里绘制它们。