【问题标题】:Drawing bitmap without scaling on Android在Android上绘制位图而不缩放
【发布时间】:2012-10-18 09:02:18
【问题描述】:

我试图在画布上绘制位图。在模拟器中,图像似乎模糊了。 android可能会自动缩放位图吗?我确实尝试禁用缩放,例如

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

模糊意味着如果我在位图中有一个像素,我会看到 2x2 像素。有时会丢失一个像素。所以我假设 Android 会自动对其进行缩放以适应不同的屏幕。我只是使用 WVGA,如何防止这种缩放?谢谢。

【问题讨论】:

    标签: android bitmap screen android-canvas scaling


    【解决方案1】:

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

    来自Bitmap.setDensity() 文档:

    指定此位图的密度。当位图绘制到 也有密度的画布,它会被适当地缩放。

    您可以致电bitmap.setDensity(Bitmap.DENSITY_NONE) 以完全禁用此自动缩放行为。如果从资源中加载位图,放在drawable-nodpi 下就足够了。

    出于好奇:此行为背后的逻辑在Canvas.cppandroid.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();
        }
    }
    

    【讨论】:

    • 我花了大约两个小时试图弄清楚是什么在缩放我的位图,而您使用该 bitmap.setDensity(Bitmap.DENSITY_NONE) 节省了我的一天。太感谢了。 :-)
    • 欢迎您!我在上一个项目中也花了一些时间,直到我意识到有这样一个功能:)
    • 我不知道为什么,但对我来说,直到我将 添加到清单中之前,Bitmap.setDensity 才被考虑在内......跨度>
    【解决方案2】:

    我认为把你的位图放在 drawable-nodpi 文件夹中可以解决这个问题。 顺便说一句,标签仅供 Google Play 使用。

    【讨论】:

      猜你喜欢
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-10
      相关资源
      最近更新 更多