在Android上绘制位图而不进行缩放

4

我试图在画布上绘制位图。在模拟器中,图像似乎有些模糊。这是android自动缩放了位图的可能性吗?我已经尝试禁用缩放,如下:

< supports-screens android:smallScreens="false" android:normalScreens="true" 
android:largeScreens="false" android:xlargeScreens="false" android:anyDensity="true" />

模糊(blur)意味着如果我在位图中有一个像素,我会看到像是2x2个像素。有时候一个像素会消失。所以我认为Android会自动缩放它以适应不同的屏幕。我只使用WVGA,如何防止这种缩放?谢谢。

2个回答

12

确实,BitmapCanvas 都有一个密度属性,在绘制位图时,如果画布和位图的密度不同,则自动缩放位图。

来自Bitmap.setDensity()文档:

指定此位图的密度。当将位图绘制到具有密度的画布上时,它会适当地缩放。

您可以调用bitmap.setDensity(Bitmap.DENSITY_NONE)来完全禁用这种自动缩放行为。如果从资源加载位图,则将其放置在drawable-nodpi下就足够了。

对于好奇的人们:此行为背后的逻辑是在Canvas.cpp中实现的(android.graphics.Canvas 的本地部分),在drawBitmap__BitmapFFPaint() 方法中实现:

static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
                                      SkCanvas* canvas, SkBitmap* bitmap,
                                      jfloat left, jfloat top,
                                      SkPaint* paint, jint canvasDensity,
                                      jint screenDensity, jint bitmapDensity) {
    SkScalar left_ = SkFloatToScalar(left);
    SkScalar top_ = SkFloatToScalar(top);

    if (canvasDensity == bitmapDensity || canvasDensity == 0
            || bitmapDensity == 0) {
        if (screenDensity != 0 && screenDensity != bitmapDensity) {
            SkPaint filteredPaint;
            if (paint) {
                filteredPaint = *paint;
            }
            filteredPaint.setFilterBitmap(true);
            canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
        } else {
            canvas->drawBitmap(*bitmap, left_, top_, paint);
        }
    } else {
        canvas->save();
        SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
        canvas->translate(left_, top_);
        canvas->scale(scale, scale);

        SkPaint filteredPaint;
        if (paint) {
            filteredPaint = *paint;
        }
        filteredPaint.setFilterBitmap(true);

        canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);

        canvas->restore();
    }
}

2
我浪费了大约两个小时来弄清楚是什么在缩放我的位图,而你通过使用bitmap.setDensity(Bitmap.DENSITY_NONE)解决了我的问题。非常感谢你,救了我的一天。 :-) - Fran Marzoa
不客气!我在上一个项目中也花了一些时间,直到我意识到有这样的功能 :) - Code Painters
我不知道为什么,但是在我的情况下,除非我在清单中添加<supports-screens android:anyDensity="true"/>,否则Bitmap.setDensity不会被考虑。 - Couitchy

0

我认为将位图放在drawable-nodpi文件夹中可以解决这个问题。 顺便说一下,<uses-feature>标签只能被Google Play使用。


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