在 SurfaceView 上绘制缩放位图 - 无抗锯齿

发布于 2024-11-09 03:31:38 字数 573 浏览 5 评论 0原文

如果这个话题之前已经被提出过,我很抱歉,但是我在网络和谷歌组上的所有搜索都没有帮助我。

我目前正在使用 Android SDK 开发一个小游戏,并使用高分辨率位图,我会相应地调整大小以匹配设备的分辨率(让系统为我做这件事是 不够“脆”)。

我使用 SurfaceView,在其上一次性绘制填充整个表面的画布。绘制使用 setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)) 来允许遮罩。 事先,我检索各种位图(这些位图在初始化时使用 createScaledBitmap() 调整大小并放入缓存中),然后在 SurfaceView 上绘制此画布之前,在该画布上使用绘画应用位图。

我的问题是,无论我尝试什么,无论我使用什么绘画设置(抖动、抗锯齿等),调整大小的位图都不会抗锯齿,并且绘图呈现锯齿状边缘。我尝试了一切。 我取得的唯一一点成功是使用 inSampleSize 来接近所需的缩放大小并强制执行第一遍抗锯齿,然后在检索到的对象上调用 createScaledBitmap 之前 高分辨率位图,但不够美观。我只是不允许为每种分辨率组合创建大量预先设定大小的位图。我错过了什么?

预先非常感谢

I'm sorry if this topic has been brought before, but all my searches on the web and google groups did not help me.

I'm currently developing a little game with the Android SDK, and use hi-res bitmaps that I resize accordingly to match the device's resolution (letting the system do it for me is
not "crisp" enough).

I use a SurfaceView, on which I paint in one pass a canvas filling the whole surface. The paint uses setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)) to allow masking.
Beforehand, I retrieve various bitmaps -- which are resized at initialization with createScaledBitmap() and put in a cache -- and I apply the bitmaps with a paint on this canvas, before drawing this canvas on the SurfaceView.

My problem is, whatever I try, whatever paint settings I use (dithering, antialias, etc..), the resized bitmaps are not antialiased and the drawing present jagged edges. I tried everything.
The only little success I had was using inSampleSize to approach the desired scaled size and force a first pass of antialiasing, before invoking createScaledBitmap on the retrieved
hi-res bitmap, but it is not beautiful enough. I just can't allow to create multitudes of pre-sized bitmaps for every combination of resolution. What did I miss ?

Thanks a lot in advance

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

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

发布评论

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

评论(3

空城旧梦 2024-11-16 03:31:38

首先,当您加载位图时,通过将选项设置为 argb_8888,确保不会丢失任何图像质量:

Options options = new Options();    
options.inScaled = false; 
options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.id.pic, options);

当缩放位图时,打开过滤器:

pic = Bitmap.createScaledBitmap(pic, screenW, screenH, true);

但是,如果图像过度拉伸,则不可避免地会降低质量。

当您使用绘画时,您可以提高质量,但通过打开抖动和过滤会损失速度:

Paint paint = new Paint(); 
paint.setFlags(Paint.DITHER_FLAG);
paint.setFilterBitmap(true);

最后,整个活动窗口可以设置在 argb_4444 上,而不是 argb_8888 上(OS < 2.3)。如果您在 setContentView 之前插入此行,则可以更改此设置:

getWindow().setFormat(PixelFormat.RGBA_8888); 

First when you load your bitmap you make sure that you don't lose any image quality by settings options to argb_8888:

Options options = new Options();    
options.inScaled = false; 
options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
Bitmap pic = BitmapFactory.decodeResource(getResources(), R.id.pic, options);

When you scale the bitmap turn on the filter:

pic = Bitmap.createScaledBitmap(pic, screenW, screenH, true);

However if one streaches the image too much inevitably it degrades in quality.

When you use paint you can improve quality but lose on speed with turning on ditherig and filtering:

Paint paint = new Paint(); 
paint.setFlags(Paint.DITHER_FLAG);
paint.setFilterBitmap(true);

Finally the entire activity window could be set on argb_4444 instead on argb_8888 (OS < 2.3). You can chage this if you instert this line before setContentView:

getWindow().setFormat(PixelFormat.RGBA_8888); 
蓝戈者 2024-11-16 03:31:38

如果归根结底,您可以手动消除锯齿,而不会有太多麻烦。只需在要求位图对象重新缩放自身之前对像素数据应用一个简单的低通滤波器(类似于 NxN 平均值)即可。

If it comes down to it, you can manually antialias without too much trouble. Just apply a simple lowpass filter (something like an NxN average) to the pixel data before asking the bitmap object to rescale itself.

心是晴朗的。 2024-11-16 03:31:38

您可以自行清除画布缓冲区!比如如下:

canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);

you may clear canvas buffer by youself! such as follows:

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