実際、との両方Bitmap
にCanvas
密度プロパティがあり、キャンバスとビットマップの密度が異なる場合、ビットマップを描画するとビットマップが自動的にスケーリングされます。
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();
}
}