web-dev-qa-db-ja.com

Android canvas drawTextテキストのy位置

Canvasを使用して、背景とテキストを含むDrawableを作成しています。ドローアブルは、EditText内の複合ドローアブルとして使用されます。

テキストはキャンバス上のdrawText()を介して描画されますが、描画されたテキストのy位置に問題がある場合があります。そのような場合、一部のキャラクターの一部が切り取られます(画像リンクを参照)。

配置の問題のない文字:

http://i50.tinypic.com/zkpu1l.jpg

配置の問題がある文字、テキストに「g」、「j」、「q」などが含まれています:

http://i45.tinypic.com/vrqxja.jpg

以下の問題を再現するためのコードスニペットを見つけることができます。

Y位置の適切なオフセットを決定する方法を知っている専門家はいますか?

public void writeTestBitmap(String text, String fileName) {
   // font size
   float fontSize = new EditText(this.getContext()).getTextSize();
   fontSize+=fontSize*0.2f;
   // Paint to write text with
   Paint paint = new Paint(); 
   Paint.setStyle(Style.FILL);  
   Paint.setColor(Color.DKGRAY);
   Paint.setAntiAlias(true);
   Paint.setTypeface(Typeface.SERIF);
   Paint.setTextSize((int)fontSize);
   // min. rect of text
   Rect textBounds = new Rect();
   Paint.getTextBounds(text, 0, text.length(), textBounds);
   // create bitmap for text
   Bitmap bm = Bitmap.createBitmap(textBounds.width(), textBounds.height(), Bitmap.Config.ARGB_8888);
   // canvas
   Canvas canvas = new Canvas(bm);
   canvas.drawARGB(255, 0, 255, 0);// for visualization
   // y = ?
   canvas.drawText(text, 0, textBounds.height(), Paint);

   try {
      FileOutputStream out = new FileOutputStream(fileName);
      bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
   } catch (Exception e) {
      e.printStackTrace();
   }
}
28
darksaga

TextBounds.bottom = 0と想定するのはおそらく間違いだと思います。これらの降順の文字の場合、これらの文字の下部はおそらく0未満です(つまり、textBounds.bottom> 0)。あなたはおそらく次のようなものを望みます:

canvas.drawText(text, 0, textBounds.top, Paint); //instead of textBounds.height()

TextBoundsが+5〜-5で、y = height(10)でテキストを描画する場合、テキストの上半分のみが表示されます。

26
Tim

左上隅近くにテキストを描画したい場合は、次のようにする必要があると思います。

canvas.drawText(text, -textBounds.left, -textBounds.top, Paint);

また、2つの座標に必要な変位量を合計することで、テキスト内を移動できます。

canvas.drawText(text, -textBounds.left + yourX, -textBounds.top + yourY, Paint);

これが機能する理由(少なくとも私にとって)は、getTextBounds()が、x = 0およびy = 0の場合に、drawText()がテキストをどこに描画するかを通知するためです。したがって、Androidでのテキストの処理方法によって導入される変位(textBounds.leftおよびtextBounds.top)を差し引くことで、この動作を打ち消す必要があります。

this answer では、このトピックについてもう少し詳しく説明します。

13
damix911