5

画面の高さに沿ってキャンバスの月のテキストを垂直に描画したい。

ペイント初期化:

   this.paint = new Paint();
   this.paint.setAntiAlias(true);
   this.paint.setDither(true);
   this.paint.setSubpixelText(true);
   this.paint.setColor(color_text_dark);
   this.paint.setTextAlign(Align.RIGHT);

描く:

   // Set the scale to the widest month
   float scale = getHeight() / this.max_month_width;
   String month_string = FULL_MONTH_NAME_FORMATTER.
                         format(active_month_calendar.getTime());
   canvas.save();
   canvas.translate(getWidth(), 0);
   canvas.rotate(-90);
   canvas.scale(scale, scale);
   canvas.drawText(month_string, 0, 0, this.paint);
   canvas.restore();

結果はhdpi 画面ではきれいに見えますが、 xhdpi画面では非常に見苦しく、ピクセル化されています

さまざまなデバイスでさらにテストを行い、結果が画面密度や解像度ではなく、Android のバージョンに依存することを理解しました。

コードは 2.x プラットフォームでは問題なく動作しますが、4.0.3 以降では動作しません。ここで Android の draw 実装を変更したとします。ここで見ることができる完全なコード。

hdpiバージョン2.3.5 ( 2.2もテスト済み)

hdpi

xhdpiバージョン4.2 ( 4.1 4.0.3もテスト済み)

xhdpi

ペイント アンチエイリアスのさまざまなバリエーションを試してみましたが、サブピクセル テキストは効果がありません。この問題を解決するにはどうすればよいですか?

4

2 に答える 2

10

問題は、テキストを1つのサイズで描画し、結果を拡大することです。テキストの幅を決定したら、Paint.measureText()の呼び出しを使用し、それに応じてPaint.setTextSize()を使用してサイズを調整する必要があります。正しく測定されたら、Canvas.drawText()を呼び出します。

別の方法は、テキストをまったく測定せず、ただちに電話することです。

paint.setTextSize(paint.getSize() * scale)

ただし、この場合にテキストが収まる保証はありません。

他の変換呼び出しはいずれも補間を行わないため、非常にシャープな線が得られるはずです。

編集

コードサンプルと比較のスクリーンショットは次のとおりです。

canvas.save();
canvas.scale(10, 10);
canvas.drawText("Hello", 0, 10, mTextPaint);
canvas.restore();
float textSize = mTextPaint.getTextSize();
mTextPaint.setTextSize(textSize * 10);
canvas.drawText("Hello", 0, 300, mTextPaint);
mTextPaint.setTextSize(textSize);

上がレンダリング方法、下が私のレンダリング方法

于 2013-01-27T00:18:16.227 に答える
2

Krylez の優れた回答についてコメントするほどの評判はありませんが、パスに関する mcfly soft のコメント/質問に返信したいと思います。

パスとテキストの考え方は同じです。パスが描かれているキャンバスをスケーリングおよび変換する代わりに、同じスケーリングと変換をマトリックスに入れ、それを Path.transform に渡します。

// instead of this:
canvas.scale(sX, sY);
canvas.translate(trX, trY);
canvas.drawPath(path);

// do this:
matrix.postScale(sX, sY);
matrix.postTranslate(trX, trY);
path.transform(matrix);
canvas.drawPath(path);
于 2015-09-21T06:41:09.523 に答える