Canvas에 여러 줄 텍스트 그리기


124

희망 빠른 질문은,하지만 난 정의에 여러 줄의 텍스트를 작성하고 싶습니다 ... 예제를 찾을 수 없습니다 View비아 (via) Canvas, 그리고에 onDraw()내가 가진 :

...
String text = "This is\nmulti-line\ntext";
canvas.drawText(text, 100, 100, mTextPaint);
...

나는 이것이 줄 바꿈으로 이어지기를 바랐지만 대신에 그것이 \n있을 수 있는 비밀스러운 문자를보고 있습니다.

감사합니다.


1
문서는 직접 Layout호출 하는 대신 사용을 권장 Canvas.drawText합니다. 이 Q & A는를 사용하여 여러StaticLayout 줄 문자를 그리는 방법을 보여줍니다 .
Suragch

답변:


26

안타깝게도 Android는 무엇인지 모릅니다 \n. 당신이해야 할 일은 \n다음 줄에 텍스트를 가져 오기 위해 Y를 벗긴 다음 오프셋하는 것입니다. 그래서 다음과 같이 :

canvas.drawText("This is", 100, 100, mTextPaint);
canvas.drawText("multi-line", 100, 150, mTextPaint);
canvas.drawText("text", 100, 200, mTextPaint);

1
따라서 텍스트를 세 개의 개별 청크로 분할 한 다음 drawText()?를 세 번 호출해야합니다 .
폴 Mennega

5
예. 방금 예를 추가했습니다. String.Split을 사용하여 '\ n'에서 분할 한 다음 각각을 오프셋합니다.
Icemanind 2011

이 아이디어에 감사드립니다.
Sumit Kumar

224

정적 레이아웃을 사용하는 다른 방법을 찾았습니다. 누구나 참조 할 수있는 코드는 다음과 같습니다.

TextPaint mTextPaint=new TextPaint();
StaticLayout mTextLayout = new StaticLayout(mText, mTextPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

canvas.save();
// calculate x and y position where your text will be placed

textX = ...
textY = ...

canvas.translate(textX, textY);
mTextLayout.draw(canvas);
canvas.restore();

3
내 의견으로는 더 나은 솔루션 .. 텍스트를 줄로 분할 할 필요가 없습니다 .. 텍스트에 처음에 줄 바꿈이 없거나 줄 바꿈이 있는지 모르는 경우 특히 편리합니다 ...
Ewoks

6
훌륭합니다. 큰 텍스트가 캔버스 높이를 벗어나는 것을 방지 할 수 있습니까?
moDev 2013-08-11

1
매우 유용하지만 StaticLayout을 중앙에 배치 할 때 TextPaint ()에서 정렬을 설정하는 방법에주의하십시오. TextPaing.setTextAlign (Align.CENTER)을 사용하면 다른 전화가 이것으로 다른 일을하기 때문에 문제가 발생했습니다.
greg7gkb 2013-08-20

2
canvas.getWidth()getWidth() - getPaddingLeft() - getPaddingRight()뷰의 패딩을 고려하려면 정말이어야합니다 . 또한 텍스트 또는 뷰 크기가 변경된 경우에만 StaticLayout을 계산하고 새 것을 구성하지 않고 그릴 수 있다는 점에 유의하십시오.
Jules 2014

1
@Eenvincible 당신은 여기 내 블로그 포스트를 확인할 수 있습니다 : skoumal.net/en/android-drawing-multiline-text-on-bitmap
gingo

98

각 행을 반복하십시오.

int x = 100, y = 100;
for (String line: text.split("\n")) {
      canvas.drawText(line, x, y, mTextPaint);
      y += mTextPaint.descent() - mTextPaint.ascent();
}

새로운 y 위치를 계산하는 적절한 방법이 있습니까? 겉으로는 임의의 숫자를 추가하면 ... 나를 매우 편안하지 않습니다
AgentKnopf

1
ascent + decent가 너무 작다고 생각되면 일정한 간격 계수를 추가하거나 곱하기 (예 : 1.5 선)하여 맛볼 수 있습니다.
Dave

1
상승이 음수임을 주목하십시오. 당신은 실제로 높이 얻을 하강 - 상승 필요
아미르 Uval

1
선택한 문자에 대한 메트릭을 가져올 수 있습니다. 예 : font.measure ( "Y")
GregD

11

나는 완전한 예를 썼다

여기에 이미지 설명 입력

colors.xml

  <color name="transparentBlack">#64000000</color>

자바 클래스

 public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.amit);
        ImageView imageView = (ImageView)findViewById(R.id.imageView);
        imageView.setImageBitmap(drawTextToBitmap(this, bm, "Name: Kolala\nDate: Dec 23 2016 12:47 PM, \nLocation: 440 Banquets & Restaurents"));

    }

  public Bitmap drawTextToBitmap(Context gContext,
                                   Bitmap bitmap,
                                   String gText) {
        Resources resources = gContext.getResources();
        float scale = resources.getDisplayMetrics().density;

        android.graphics.Bitmap.Config bitmapConfig =
                bitmap.getConfig();
        // set default bitmap config if none
        if(bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
        }
        // resource bitmaps are imutable,
        // so we need to convert it to mutable one
        bitmap = bitmap.copy(bitmapConfig, true);

        Canvas canvas = new Canvas(bitmap);
        // new antialised Paint
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        // text color - #3D3D3D
        paint.setColor(Color.WHITE);
        // text size in pixels
        paint.setTextSize((int) (25 * scale));
        // text shadow
        paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);

        // draw text to the Canvas center
        Rect bounds = new Rect();

        int noOfLines = 0;
        for (String line: gText.split("\n")) {
           noOfLines++;
        }

        paint.getTextBounds(gText, 0, gText.length(), bounds);
        int x = 20;
        int y = (bitmap.getHeight() - bounds.height()*noOfLines);

        Paint mPaint = new Paint();
        mPaint.setColor(getResources().getColor(R.color.transparentBlack));
        int left = 0;
        int top = (bitmap.getHeight() - bounds.height()*(noOfLines+1));
        int right = bitmap.getWidth();
        int bottom = bitmap.getHeight();
        canvas.drawRect(left, top, right, bottom, mPaint);

        for (String line: gText.split("\n")) {
            canvas.drawText(line, x, y, paint);
            y += paint.descent() - paint.ascent();
        }

        return bitmap;
    }
}

4
루프를 사용하여 줄을 세는 이유는 무엇입니까? int noOfLines = gText.split("\n").length
Tomasz

9

이것은 @Dave의 답변을 기반으로 한 내 솔루션입니다 (감사합니다 btw ;-))

import android.graphics.Canvas;
import android.graphics.Paint;

public class mdCanvas
{
    private Canvas m_canvas;

    public mdCanvas(Canvas canvas)
    {
        m_canvas = canvas;
    }

    public void drawMultiline(String str, int x, int y, Paint paint)
    {
        for (String line: str.split("\n"))
        {
              m_canvas.drawText(line, x, y, paint);
              y += -paint.ascent() + paint.descent();
        }
    }
}

Canvas를 상속하려고했지만 실제로는 허용하지 않습니다. 그래서 이것은 중간 클래스입니다!


1
이렇게 해봤는데 .. 내 가장 큰 줄 마지막 단어 마지막 글자가 반만 보여준 것 외에는 모든 것이 잘 작동합니다. ?
Aada

8

여기에 STROKE WIDTH도 고려하는 버전을 추가해야합니다.

void drawMultiLineText(String str, float x, float y, Paint paint, Canvas canvas) {
   String[] lines = str.split("\n");
   float txtSize = -paint.ascent() + paint.descent();       

   if (paint.getStyle() == Style.FILL_AND_STROKE || paint.getStyle() == Style.STROKE){
      txtSize += paint.getStrokeWidth(); //add stroke width to the text size
   }
   float lineSpace = txtSize * 0.2f;  //default line spacing

   for (int i = 0; i < lines.length; ++i) {
      canvas.drawText(lines[i], x, y + (txtSize + lineSpace) * i, paint);
   }
}

6

작동합니다. 나는 테스트했다

 public Bitmap drawMultilineTextToBitmap(Context gContext,
                                       int gResId,
                                       String gText) {    
      // prepare canvas
      Resources resources = gContext.getResources();
      float scale = resources.getDisplayMetrics().density;
      Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);

      android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
      // set default bitmap config if none
      if(bitmapConfig == null) {
        bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
      }
      // resource bitmaps are imutable,
      // so we need to convert it to mutable one
      bitmap = bitmap.copy(bitmapConfig, true);

      Canvas canvas = new Canvas(bitmap);

      // new antialiased Paint
      TextPaint paint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
      // text color - #3D3D3D
      paint.setColor(Color.rgb(61, 61, 61));
      // text size in pixels
      paint.setTextSize((int) (14 * scale));
      // text shadow
      paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);

      // set text width to canvas width minus 16dp padding
      int textWidth = canvas.getWidth() - (int) (16 * scale);

      // init StaticLayout for text
      StaticLayout textLayout = new StaticLayout(
        gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);

      // get height of multiline text
      int textHeight = textLayout.getHeight();

      // get position of text's top left corner
      float x = (bitmap.getWidth() - textWidth)/2;
      float y = (bitmap.getHeight() - textHeight)/2;

      // draw text to the Canvas center
      canvas.save();
      canvas.translate(x, y);
      textLayout.draw(canvas);
      canvas.restore();

      return bitmap;
    }

출처 : http://www.skoumal.net/en/android-drawing-multiline-text-on-bitmap/


사용하는 동안 Bitmap image = BitmapFactory.decodeResource (mContext.getResources (), R.drawable.transparent_flag); 그것은 잘 작동하지만 내가 insted 텍스트보기 ID를 사용하면 작동하지 않습니다
DKV

고마워요, 제가 원하는대로 작동했지만 텍스트를 편집하거나 다른 위치로 슬라이드하는 데 도움을 줄 수 있다면 포토샵처럼 미리 감사드립니다.
kvadityaaz

5

예. canvas.getFontSpacing()증분으로 사용 합니다. 나는 호기심에서 직접 시도했으며 모든 글꼴 크기에서 작동합니다.


2
난 당신 말은 생각 Paint.getFontSpacing
호세 M.

5

이 시도

Paint paint1 = new Paint();
paint1.setStyle(Paint.Style.FILL);
paint1.setAntiAlias(true);
paint1.setColor(Color.BLACK);
paint1.setTextSize(15);


TextView tv = new TextView(context);
tv.setTextColor(Color.BLACK);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(5, 2, 0, 0); // llp.setMargins(left, top, right, bottom);
tv.setLayoutParams(llp);
tv.setTextSize(10);
String text="this is good to see you , i am the king of the team";

tv.setText(text);
tv.setDrawingCacheEnabled(true);
tv.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
canvas.drawBitmap(tv.getDrawingCache(), 5, 10, paint1);
tv.setDrawingCacheEnabled(false);

6
나는 이것이 onDraw에서하지 말아야 할 것의 완벽한 예라고 생각합니다.
rupps

@rupps 예,이 모든 것을 onDraw에 포함시키는 것은 완전한 과잉 일 수 있지만 대답은 그렇게하라고 말하지 않습니다. 그리고 아이디어는 천재적입니다 (그리고 그것은 내 문제를 해결했습니다). StaticLayout 및 String.split을 조이십시오!
Rodia

4

GreenBee가 제안한 솔루션을 재사용하고 잘림이 발생하면 끝에 "..."가있는 지정된 경계에 여러 줄 텍스트를 그리는 기능을 만들었습니다.

public static void drawMultiLineEllipsizedText(final Canvas _canvas, final TextPaint _textPaint, final float _left,
            final float _top, final float _right, final float _bottom, final String _text) {
        final float height = _bottom - _top;

        final StaticLayout measuringTextLayout = new StaticLayout(_text, _textPaint, (int) Math.abs(_right - _left),
                Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

        int line = 0;
        final int totalLineCount = measuringTextLayout.getLineCount();
        for (line = 0; line < totalLineCount; line++) {
            final int lineBottom = measuringTextLayout.getLineBottom(line);
            if (lineBottom > height) {
                break;
            }
        }
        line--;

        if (line < 0) {
            return;
        }

        int lineEnd;
        try {
            lineEnd = measuringTextLayout.getLineEnd(line);
        } catch (Throwable t) {
            lineEnd = _text.length();
        }
        String truncatedText = _text.substring(0, Math.max(0, lineEnd));

        if (truncatedText.length() < 3) {
            return;
        }

        if (truncatedText.length() < _text.length()) {
            truncatedText = truncatedText.substring(0, Math.max(0, truncatedText.length() - 3));
            truncatedText += "...";
        }
        final StaticLayout drawingTextLayout = new StaticLayout(truncatedText, _textPaint, (int) Math.abs(_right
                - _left), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

        _canvas.save();
        _canvas.translate(_left, _top);
        drawingTextLayout.draw(_canvas);
        _canvas.restore();
    }

3
텍스트가 잘 리면 코드가 공백에 맞는 전체 단어를 잘릴 수 있습니다. 따라서 여기에 코드를 개선하기위한 작은 제안이 있습니다. 세 문자 "..."를 세 개의 점이 포함 된 "..."(HTML의 & hellip; 코드)로만 바꾸십시오. 그런 다음 3 개 대신 하나의 문자 (대개 공백) 만 제거하고 단어를 자르지 않은 상태로 유지할 수 있습니다. truncatedText = truncatedText.substring (0, Math.max (0, truncatedText.length ()-1));
Asterius

2

StaticLayout없는 솔루션

//Get post text
    String text = post.getText();

    //Get weight of space character in px
    float spaceWeight = paint.measureText(" ");

    //Start main algorithm of drawing words on canvas
    //Split text to words
    for (String line : text.split(" ")) {
        //If we had empty space just continue
        if (line.equals("")) continue;
        //Get weight of the line
        float lineWeight = paint.measureText(line);
        //If our word(line) doesn't have any '\n' we do next
        if (line.indexOf('\n') == -1) {
            //If word can fit into current line
            if (cnv.getWidth() - pxx - defaultMargin >= lineWeight) {
                //Draw text
                cnv.drawText(line, pxx, pxy, paint);
                //Move start x point to word weight + space weight
                pxx += lineWeight + spaceWeight;
            } else {
                //If word can't fit into current line
                //Move x point to start
                //Move y point to the next line
                pxx = defaultMargin;
                pxy += paint.descent() - paint.ascent();
                //Draw
                cnv.drawText(line, pxx, pxy, paint);
                //Move x point to word weight + space weight
                pxx += lineWeight + spaceWeight;
            }
            //If line contains '\n'
        } else {
            //If '\n' is on the start of the line
            if (line.indexOf('\n') == 0) {
                pxx = defaultMargin;
                pxy += paint.descent() - paint.ascent();
                cnv.drawText(line.replaceAll("\n", ""), pxx, pxy, paint);
                pxx += lineWeight + spaceWeight;
            } else {
                //If '\n' is somewhere in the middle
                //and it also can contain few '\n'
                //Split line to sublines
                String[] subline = line.split("\n");
                for (int i = 0; i < subline.length; i++) {
                    //Get weight of new word
                    lineWeight = paint.measureText(subline[i]);
                    //If it's empty subline that's mean that we have '\n'
                    if (subline[i].equals("")) {
                        pxx = defaultMargin;
                        pxy += paint.descent() - paint.ascent();
                        cnv.drawText(subline[i], pxx, pxy, paint);
                        continue;
                    }
                    //If we have only one word
                    if (subline.length == 1 && i == 0) {
                        if (cnv.getWidth() - pxx >= lineWeight) {
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                        } else {
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                        }
                        continue;
                    }
                    //If we have set of words separated with '\n'
                    //it is the first word
                    //Make sure we can put it into current line
                    if (i == 0) {
                        if (cnv.getWidth() - pxx >= lineWeight) {
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                        } else {
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                        }
                    } else {
                        pxx = defaultMargin;
                        pxy += paint.descent() - paint.ascent();
                        cnv.drawText(subline[i], pxx, pxy, paint);
                        pxx += lineWeight + spaceWeight;
                    }
                }

            }
        }
    }

2

나는 이미 한 줄을 캔버스로 변환 한 내가 가지고있는 작업을하고 Lumis의 대답을 작업했고 결국 이것으로 끝났습니다. 1.3 및 1.3f는 글꼴 크기에 비례하여 줄 사이의 패딩을 의미합니다.

public static Bitmap getBitmapFromString(final String text, final String font, int textSize, final int textColor)
{
    String lines[] = text.split("\n");
    textSize = getRelX(textSize);  //a method in my app that adjusts the font size relative to the screen size
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setTextSize(textSize);
    paint.setColor(textColor);
    paint.setTextAlign(Paint.Align.LEFT);
    Typeface face = Typeface.createFromAsset(GameActivity.getContext().getAssets(),GameActivity.getContext().getString(R.string.font) + font + GameActivity.getContext().getString(R.string.font_ttf));
    paint.setTypeface(face);
    float baseline = -paint.ascent(); // ascent() is negative
    int width = (int) (paint.measureText(text) + 0.5f); // round
    int height = (int) (baseline + paint.descent() + 0.5f);
    Bitmap image = Bitmap.createBitmap(width, (int)(height * 1.3 * lines.length), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(image);
    for (int i = 0; i < lines.length; ++i)
    {
        canvas.drawText(lines[i], 0, baseline + textSize * 1.3f * i, paint);
    }
    return image;
}

0

비슷한 문제에 직면했습니다. 하지만 텍스트 경로를 반환해야합니다. 캔버스에이 경로를 그릴 수 있습니다. 이것은 내 코드입니다. Break Text를 사용합니다. 및 path.op

           public Path createClipPath(int width, int height) {
            final Path path = new Path();
            if (textView != null) {
                mText = textView.getText().toString();
                mTextPaint = textView.getPaint();
                float text_position_x = 0;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    text_position_x = findTextBounds(textView).left;

                }
                boolean flag = true;
                int line = 0;
                int startPointer = 0;
                int endPointer = mText.length();

                while (flag) {
                    Path p = new Path();
                    int breakText = mTextPaint.breakText(mText.substring(startPointer), true, width, null);
                    mTextPaint.getTextPath(mText, startPointer, startPointer + breakText, text_position_x,
                            textView.getBaseline() + mTextPaint.getFontSpacing() * line, p);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        path.op(p, Path.Op.UNION);
                    }
                    endPointer -= breakText;
                    startPointer += breakText;
                    line++;
                    if (endPointer == 0) {
                        flag = false;
                    }
                }

            }
            return path;
        }

텍스트 바인딩을 찾기 위해이 기능을 사용했습니다.

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private Rect findTextBounds(TextView textView) {
    // Force measure of text pre-layout.
    textView.measure(0, 0);
    String s = (String) textView.getText();

    // bounds will store the rectangle that will circumscribe the text.
    Rect bounds = new Rect();
    Paint textPaint = textView.getPaint();

    // Get the bounds for the text. Top and bottom are measured from the baseline. Left
    // and right are measured from 0.
    textPaint.getTextBounds(s, 0, s.length(), bounds);
    int baseline = textView.getBaseline();
    bounds.top = baseline + bounds.top;
    bounds.bottom = baseline + bounds.bottom;
    int startPadding = textView.getPaddingStart();
    bounds.left += startPadding;

    // textPaint.getTextBounds() has already computed a value for the width of the text,
    // however, Paint#measureText() gives a more accurate value.
    bounds.right = (int) textPaint.measureText(s, 0, s.length()) + startPadding;
    return bounds;
}


0

여러 줄 텍스트를 그리는 것 외에도 여러 줄 텍스트 경계 를 얻는 데 어려움을 겪을 수 있습니다 (예 : 캔버스에 정렬하기 위해). 이 경우
기본값 paint.getTextBounds()은 유일한 선을 측정하므로 작동하지 않습니다.

편의를 위해 두 가지 확장 함수를 만들었습니다. 하나는 여러 줄 텍스트를 그리기위한 것이고 다른 하나는 텍스트 경계를 얻기위한 것입니다.

private val textBoundsRect = Rect()

/**
 * Draws multi-line text on the Canvas with the origin at (x,y), using the specified paint. The origin is interpreted
 * based on the Align setting in the paint.
 *
 * @param text The text to be drawn
 * @param x The x-coordinate of the origin of the text being drawn
 * @param y The y-coordinate of the baseline of the text being drawn
 * @param paint The paint used for the text (e.g. color, size, style)
 */
fun Canvas.drawTextMultiLine(text: String, x: Float, y: Float, paint: Paint) {
    var lineY = y
    for (line in text.split("\n")) {
        lineY += paint.descent().toInt() - paint.ascent().toInt()
        drawText(line, x, lineY, paint)
    }
}

/**
 * Retrieve the text boundary box, taking into account line breaks [\n] and store to [boundsRect].
 *
 * Return in bounds (allocated by the caller [boundsRect] or default mutable [textBoundsRect]) the smallest rectangle that
 * encloses all of the characters, with an implied origin at (0,0).
 *
 * @param text string to measure and return its bounds
 * @param start index of the first char in the string to measure. By default is 0.
 * @param end 1 past the last char in the string to measure. By default is test length.
 * @param boundsRect rect to save bounds. Note, you may not supply it. By default, it will apply values to the mutable [textBoundsRect] and return it.
 * In this case it will be changed by each new this function call.
 */
fun Paint.getTextBoundsMultiLine(
    text: String,
    start: Int = 0,
    end: Int = text.length,
    boundsRect: Rect = textBoundsRect
): Rect {
    getTextBounds(text, start, end, boundsRect)
    val linesCount = text.split("\n").size
    val allLinesHeight = (descent().toInt() - ascent().toInt()) * linesCount
    boundsRect.bottom = boundsRect.top + allLinesHeight
    return boundsRect
}

이제 사용은 다음과 같이 쉽습니다. 여러 줄 문자를 그리는 경우 :

canvas.drawTextMultiLine(text, x, y, yourPaint)

텍스트 측정 :

val bounds = yourPaint.getTextBoundsMultiLine (text)

이 경우 처음부터 끝까지 모든 텍스트를 측정하고 일단 할당 된 (변경 가능한) Rect를 기본값으로 사용합니다.
추가 유연성을 위해 추가 매개 변수를 전달하여 놀 수 있습니다.


-1

동적 텍스트 크기 조정 및 간격을 사용한 나의 예, 나를 위해 잘 작동합니다 ...

public Bitmap fontTexture(String string, final Context context) {
    float text_x = 512;
    float text_y = 512;
    final float scale = context.getResources().getDisplayMetrics().density;

    int mThreshold = (int) (THRESHOLD_DIP * scale + 0.5f);

    String[] splited = string.split("\\s+");
    double longest = 0;
    for(String s:splited){
        if (s.length() > longest) {
            longest = s.length();
        }
    }
    if(longest > MAX_STRING_LENGTH) {
        double ratio = (double) MAX_STRING_LENGTH / longest;
        mThreshold = (int) ((THRESHOLD_DIP * ((float) ratio)) * scale + 0.5f);
    }

    Bitmap bitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmap);

    Typeface font = Typeface.createFromAsset(context.getAssets(),
            "fonts/dotted_font.ttf");

    TextPaint mTextPaint=new TextPaint();
    mTextPaint.setColor(Color.YELLOW);
    mTextPaint.setTextAlign(Paint.Align.CENTER);
    mTextPaint.setTextSize(mThreshold);
    mTextPaint.setTypeface(font);
    StaticLayout mTextLayout = new StaticLayout(string, mTextPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

    canvas.save();

    canvas.translate(text_x, text_y);
    mTextLayout.draw(canvas);
    canvas.restore();


    return bitmap;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.