Drawing bitmap without scaling on Android

后端 未结 2 440
悲&欢浪女
悲&欢浪女 2021-01-06 06:26

I was trying to drawbitmap on a canvas. In the emulator, it seems that the image is blurred. Is it likely that the android automatically scaled the bitmap? I did try to d

相关标签:
2条回答
  • 2021-01-06 07:04

    Indeed, both Bitmap and Canvas have a density property, drawing a bitmap automatically scales the bitmap if the densities of the canvas and bitmap differ.

    From Bitmap.setDensity() documentation:

    Specifies the density for this bitmap. When the bitmap is drawn to a Canvas that also has a density, it will be scaled appropriately.

    You can call bitmap.setDensity(Bitmap.DENSITY_NONE) to disable this automatic scaling behavior altogether. If you load the bitmap from resources, placing it under drawable-nodpi should be enough.

    For the curious: the logic behind this behavior is implemented in Canvas.cpp (native part of the android.graphics.Canvas), in the drawBitmap__BitmapFFPaint() method:

    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();
        }
    }
    
    0 讨论(0)
  • 2021-01-06 07:26

    I think put you bitmap in drawable-nodpi folder will fix this problem. BTW, tag only be used by Google Play.

    0 讨论(0)
提交回复
热议问题