.drawtext
を使用して、特定の幅のcanvas
にテキストを描画したい
たとえば、入力テキストが何であっても、テキストの幅は常に400px
である必要があります。
入力テキストが長い場合はフォントサイズが小さくなり、入力テキストが短い場合はそれに応じてフォントサイズが大きくなります。
より効率的な方法は次のとおりです。
_/**
* Sets the text size for a Paint object so a given string of text will be a
* given width.
*
* @param Paint
* the Paint to set the text size for
* @param desiredWidth
* the desired width
* @param text
* the text that should be that width
*/
private static void setTextSizeForWidth(Paint paint, float desiredWidth,
String text) {
// Pick a reasonably large value for the test. Larger values produce
// more accurate results, but may cause problems with hardware
// acceleration. But there are workarounds for that, too; refer to
// http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
final float testTextSize = 48f;
// Get the bounds of the text, using our testTextSize.
Paint.setTextSize(testTextSize);
Rect bounds = new Rect();
Paint.getTextBounds(text, 0, text.length(), bounds);
// Calculate the desired size as a proportion of our testTextSize.
float desiredTextSize = testTextSize * desiredWidth / bounds.width();
// Set the Paint for that size.
Paint.setTextSize(desiredTextSize);
}
_
それから、あなたがする必要があるのはsetTextSizeForWidth(Paint, 400, str);
(400は質問の幅の例です)です。
さらに効率を上げるために、Rect
を静的なクラスメンバーにして、毎回インスタンス化されないようにすることができます。ただし、これにより同時実行性の問題が発生する可能性があり、間違いなくコードの明快さが妨げられます。
これを試して:
/**
* Retrieve the maximum text size to fit in a given width.
* @param str (String): Text to check for size.
* @param maxWidth (float): Maximum allowed width.
* @return (int): The desired text size.
*/
private int determineMaxTextSize(String str, float maxWidth)
{
int size = 0;
Paint paint = new Paint();
do {
Paint.setTextSize(++ size);
} while(Paint.measureText(str) < maxWidth);
return size;
} //End getMaxTextSize()
Michael Scheper's solution 良いように見えますが、私にはうまくいきませんでした。ビューで描画できる最大のテキストサイズを取得する必要がありましたが、このアプローチは設定した最初のテキストサイズに依存します。異なるサイズを設定すると、さまざまな結果が得られますが、それはあらゆる状況で正しい答えだとは言えません。
だから私は別の方法を試しました:
private float calculateMaxTextSize(String text, Paint paint, int maxWidth, int maxHeight) {
if (text == null || Paint == null) return 0;
Rect bound = new Rect();
float size = 1.0f;
float step= 1.0f;
while (true) {
Paint.getTextBounds(text, 0, text.length(), bound);
if (bound.width() < maxWidth && bound.height() < maxHeight) {
size += step;
Paint.setTextSize(size);
} else {
return size - step;
}
}
}
簡単です。テキストの長方形のサイズがmaxWidth
とmaxHeight
に十分近づくまでテキストサイズを大きくし、ループの繰り返しを減らすためにstep
を大きな値に変更します( 精度vs速度)、これを達成する最善の方法ではないかもしれませんが、機能します。