Canvas에 그릴 텍스트 높이 측정 (Android) 높이를 얻는

텍스트 높이를 측정하는 간단한 방법은 무엇입니까? 내가 지금하고있는 방법은 페인트를 사용 measureText()하여 너비를 얻은 다음 시행 착오를 통해 대략적인 높이를 얻는 것입니다. 나는 또한 엉망 FontMetrics이되었지만, 이것들은 모두 대략적인 방법처럼 보입니다.

다른 해상도로 조정하려고합니다. 나는 그것을 할 수 있지만, 상대적인 크기를 결정하기 위해 많은 계산으로 엄청나게 장황한 코드로 끝납니다. 난 싫어! 더 좋은 방법이 있어야합니다.



답변

paint.getTextBounds () (객체 메소드) 는 어떻습니까 ?


답변

필요한 것에 따라 높이를 측정하는 방법은 여러 가지가 있습니다.

getTextBounds

적은 양의 고정 텍스트를 정확하게 가운데에 맞추는 것과 같은 일을하는 경우 원할 것 getTextBounds입니다. 이처럼 경계 사각형을 얻을 수 있습니다

Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
int height = bounds.height();

다음 이미지에서 볼 수 있듯이 문자열마다 다른 높이가 표시됩니다 (빨간색으로 표시).

텍스트의 크기에 관계없이 일정한 높이가 필요한 경우에 따라 높이가 다른 것이 단점이 될 수 있습니다. 다음 섹션을 참조하십시오.

Paint.FontMetrics

글꼴 메트릭에서 글꼴의 높이를 계산할 수 있습니다. 높이는 특정 텍스트 문자열이 아닌 글꼴에서 가져 오기 때문에 항상 동일합니다.

Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float height = fm.descent - fm.ascent;

기준선은 텍스트가있는 선입니다. 하강은 일반적으로 캐릭터가 선 아래로 가장 먼 곳이며 상승은 일반적으로 캐릭터가 선 위로 가장 먼 곳입니다. 높이를 얻으려면 음수 가기 때문에 상승을 빼야합니다. (기준선이다 y=0y스크린까지 descreases).

다음 이미지를보십시오. 두 문자열의 높이는입니다 234.375.

텍스트 높이가 아닌 선 높이를 원하면 다음을 수행 할 수 있습니다.

float height = fm.bottom - fm.top + fm.leading; // 265.4297

이것 bottomtop라인입니다. 선행 (인라인 간격)은 일반적으로 0이지만 어쨌든 추가해야합니다.

위의 이미지는 이 프로젝트 에서 나온 것입니다 . 이것으로 놀아서 Font Metrics의 작동 방식을 볼 수 있습니다.

정적 레이아웃

여러 줄 문자의 높이를 측정하려면을 사용해야합니다 StaticLayout. 이 답변 에서 그것에 대해 자세히 이야기 했지만이 높이를 얻는 기본 방법은 다음과 같습니다.

String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";

TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);

int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;

StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);

float height = myStaticLayout.getHeight(); 

답변

@bramp의 대답은 정확합니다. 부분적으로 계산 된 경계가 암시 적 시작 좌표가 0, 0 인 텍스트를 완전히 포함하는 최소 사각형이라는 점은 언급하지 않았기 때문입니다.

즉, 예를 들어 “Py”의 높이는 픽셀 단위로 다른 높이가 필요하기 때문에 “py”또는 “hi”또는 “oi”또는 “aw”의 높이와 다릅니다.

이것은 결코 고전적인 자바의 FontMetrics와 동등하지 않습니다.

텍스트의 너비는 고통스럽지 않지만 높이는 큽니다.

특히, 그려진 텍스트를 세로로 가운데 정렬해야하는 경우, 그리려는 텍스트를 사용하는 대신 따옴표없이 텍스트 “a”의 경계를 가져와보십시오. 나를 위해 작동합니다 …

여기 내가 의미하는 바가있다 :

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);

paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(textSize);

Rect bounds = new Rect();
paint.getTextBounds("a", 0, 1, bounds);

buffer.drawText(this.myText, canvasWidth >> 1, (canvasHeight + bounds.height()) >> 1, paint);
// remember x >> 1 is equivalent to x / 2, but works much much faster

텍스트를 세로로 가운데 정렬한다는 것은 경계 사각형을 세로로 가운데 정렬하는 것을 의미합니다. 이는 텍스트 (대문자, 긴 글자 등)마다 다릅니다. 그러나 실제로 원하는 것은 렌더링 된 텍스트의 기준선을 정렬하여 높이가 높거나 그루브가 나타나지 않도록하는 것입니다. 따라서 가장 작은 문자의 중심 (예 : “a”)을 알고있는 한 나머지 텍스트에 대한 정렬을 재사용 할 수 있습니다. 그러면 모든 텍스트가 중앙 정렬되고 기본 정렬됩니다.


답변

높이는 페인트 변수에서 설정 한 텍스트 크기입니다.

높이를 찾는 또 다른 방법은

mPaint.getTextSize();

답변

당신은 사용할 수 있습니다 android.text.StaticLayout필요한 범위를 지정한 다음 전화 클래스 getHeight(). draw(Canvas)메소드 를 호출하여 레이아웃에 포함 된 텍스트를 그릴 수 있습니다 .


답변

getTextSize () 메서드를 사용하여 Paint 객체의 텍스트 크기를 간단히 얻을 수 있습니다. 예를 들면 다음과 같습니다.

Paint mTextPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
//use densityMultiplier to take into account different pixel densities
final float densityMultiplier = getContext().getResources()
            .getDisplayMetrics().density;
mTextPaint.setTextSize(24.0f*densityMultiplier);

//...

float size = mTextPaint.getTextSize();

답변

대신 Rect.width()Rect.Height()에서 반환 된 것을 사용해야합니다 getTextBounds(). 그것은 나를 위해 작동합니다.