安卓:将多个位图绘制在另一个位图上

4

我正在尝试从多个较小的位图合成背景位图。我正在使用带有Android SDK的Eclipse。

我已经加载了一个(大部分)空白背景位图(像素尺寸为320x480),如下所示:

Bitmap mBackground = BitmapFactory.decodeResource( res, R.drawable.background );

然后我以同样的方式加载了一个位图“tile”(128x128)。

我尝试了多种方法来将瓷砖绘制到位图上,但每种方法都不能按照我希望/预期的方式工作。我想要将瓷砖位图缩小到64x64并放置在背景位图的特定位置(像素偏移处)。

1)使用画布...

Canvas c = new Canvas( mBackground );
c.drawBitmap( mTile, null, new Rect( 10, 10, 73, 73 ), null );

这会将图块绘制得太大(不是全尺寸,也不是64x64,而是介于两者之间,大约为原始大小的66%)。
2)使用可绘制对象(基本上看起来是相同的):
Canvas c = new Canvas( mBackground );
c.translate( 10, 10 );
d.setBounds( 0, 0, 63, 63 );
d.draw( c );

实验#1的结果相同...

文档在多个地方提到(没有简明的解释),这与设备独立的“密度”有关,因此我尝试了下一个方法...

3)使用固定比例的资源。我创建了/res/drawable-nodpi(我也尝试了/res/drawable)文件夹,并将我的资源(背景和平铺png图像)移动到其中。这会导致在从背景位图创建画布时出现异常,因为未缩放的位图显然变为不可变,因此无法分配给画布!

4)我尝试使用BitmapFactory.Options并将inScaled设置为false,并将这些选项传递给背景和平铺的两个decodeResource调用。这与#3具有完全相同的效果(抛出异常)。

没有任何办法可行,这让人非常沮丧。我确定我只是错过了一些关于不同坐标空间的位图的细节,但我无法在文档或其他地方找到它(我已经尝试了多个Android开发网站,但都没有找到)。

希望有做过这个的人能看到这个请求!谢谢,Jason


为什么不使用Bitmap.createScaledBitmap()将“tile”从128x128缩放到64x64? - Zelimir
基本上,在尝试了几次实验后,似乎不可能使用合成。如果我将所有瓷砖分别加载并在飞行中组合位图(即一次性将所有内容绘制到空画布上),它可以正常工作,因为坐标空间完全匹配。 - Jason Smythe
2个回答

0

Canvas.drawBitmap() 据我所知不会执行缩放。

由于您的瓷砖图像最初是 128x128,而您想将其绘制为 64x64,最简单的技巧是使用缩小选项调用 decodeResource():

BitmapFactory.Options options = new BitmapFactory.Options()
options.inSampleSize = 2; // downscale by 50%
Bitmap mTile = BitmapFactory.decodeResource( res, R.drawable.tile, options );

为了实现更强大的缩放(例如以任意大小绘制图像),您应该将其包装在BitmapDrawable中。

我并不总是想把128缩小到64。我可能应该选择一个更好的例子,或者至少更加通用 :) - Jason Smythe
如果是这种情况,根据答案的最后一行,BitmapDrawable 就是你的好朋友。 - Reuben Scratton
你的回答中的链接已经失效了,你忘记在 .html 中加入 'l' 了。 - Kevin

0

看起来你的位图密度不同... 这里有一个类似的问题。你应该检查加载的每个位图的密度,看看是否是同样的问题。


根据getDensity()调用,它们都是160。未缩放位图的不可变性(请参见原问题中的#3和#4编辑)似乎阻止我能够合成,然后缩放最终图像。 - Jason Smythe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接