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 disable the scaling such as
< supports-screens android:smallScreens="false" android:normalScreens="true"
android:largeScreens="false" android:xlargeScreens="false" android:anyDensity="true" />
blur means if I have a pixel in the bitmap, I am seeing like 2x2 pixel. soemtimes a pixel is missing. so I assumed that Android automatically scaled it to fit different screens. I am just use WVGA and how do I prevent this scaling? Thanks.
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();
}
}
I think put you bitmap in drawable-nodpi folder will fix this problem.
BTW, tag only be used by Google Play.