Я пытаюсь нарисовать текст на изображениях разных размеров. Изображение отображается в ImageView
, а затем рисуется в Canvas
. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '*' * '* * * * * * *, Хотя ImageView
сохраняет исходную высоту и ширину изображения, но в *1004* изображение выглядит намного меньше, поэтому очень неудобно выбирать подходящий размер текста для Canvas
, поскольку ImageView
дает ложное восприятие о том, как текст будет отображаться на изображении.
Чтобы столкнуться с этой проблемой, я решил использовать кросс-умножение, чтобы найти подходящий размер текста для текста на Canvas
, который, как предполагается, появляется на Canvas
, как и на ImageView
. Вот моя попытка:
textSize = topTextView.getTextSize();
imageViewArea = ((img.getWidth()) * (img.getHeight()));
canvasArea = ((canvas.getWidth()) * (canvas.getHeight()));
x = (((textSize)/(imageViewArea)) * (canvasArea));
Первая строка получает размер текста, который появляется на ImageView
. 2-я и 3-я строки вычисляют площадь ImageView
и Canvas
. Третья строка в основном собирает все вместе и (в идеале) выводит значение с плавающей запятой, которое должно быть размером текста, нарисованного на Canvas
.
Однако это не близко к тому, как это должно быть. Текст неразборчив, когда его рисуют на маленьких изображениях. Тонкий и уродливый, когда его рисуют на изображениях среднего размера. По сути, это не похоже на предварительный просмотр.
Мое предположение таково: перекрестное умножение - не тот путь.
Есть предложения?
public Bitmap createMeme(ImageView img){
BitmapDrawable bitmapDrawable = ((BitmapDrawable) img.getDrawable());
Bitmap bitmap = bitmapDrawable.getBitmap();
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
String topText = topTextView.getText().toString();
String bottomText = bottomTextView.getText().toString();
topText = topText.toUpperCase();
bottomText = bottomText.toUpperCase();
Canvas canvas = new Canvas(mutableBitmap);
TextPaint topFillPaint = new TextPaint();
TextPaint bottomFillPaint = new TextPaint();
TextPaint topStrokePaint = new TextPaint();
TextPaint bottomStrokePaint = new TextPaint();
Typeface typeface = getResources().getFont(R.font.impact);
textSize = topTextView.getTextSize();
imageViewArea = ((img.getWidth()) * (img.getHeight()));
canvasArea = ((canvas.getWidth()) * (canvas.getHeight()));
val = textSize * sqrt(canvasArea / imageViewArea);
x = (float)val;
topFillPaint.setColor(Color.WHITE);
topFillPaint.setTextSize(x);
topFillPaint.setTypeface(typeface);
topStrokePaint.setStyle(Paint.Style.STROKE);
topStrokePaint.setStrokeWidth(4);
topStrokePaint.setTextSize(x);
topStrokePaint.setColor(Color.BLACK);
topStrokePaint.setTypeface(typeface);
bottomFillPaint.setColor(Color.WHITE);
bottomFillPaint.setTextSize(x);
bottomFillPaint.setTypeface(typeface);
bottomStrokePaint.setStyle(Paint.Style.STROKE);
bottomStrokePaint.setStrokeWidth(4);
bottomStrokePaint.setColor(Color.BLACK);
bottomStrokePaint.setTextSize(x);
bottomStrokePaint.setTypeface(typeface);
StaticLayout topFillLayout = new StaticLayout(topText, topFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
0.8f, 0.0f, false);
StaticLayout topStrokeLayout = new StaticLayout(topText, topStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
0.8f, 0.0f, false);
StaticLayout bottomFillLayout = new StaticLayout(bottomText, bottomFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
0.8f, 0.0f, false);
StaticLayout bottomStrokeLayout = new StaticLayout(bottomText, bottomStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
0.8f, 0.0f, false);
topFillLayout.draw(canvas);
topStrokeLayout.draw(canvas);
canvas.translate(0, canvas.getHeight() - 50);
bottomFillLayout.draw(canvas);
bottomStrokeLayout.draw(canvas);
return mutableBitmap;
}
OUTPUT
Итак, я загрузил 4 изображения с разными размерами, чтобы увидеть размер текста для каждого из них. Вот мои выводы:
274 x 184
topTextSize: 0, bottomTextSize: 0
3704 x 2469
topTextSize: 237,58, bottomTextSize: 237,58
640 x 480
topTextSize: 0, bottomTextSize: 0
2560 x 1920
topTextSize: 168, bottomTextSize: 168
Для 2
и 4
, только верхний текст отображается на растровом изображении
Например, вот значения для изображения с размерами 274 x 184
:
textSize = 168
imageViewArea = 1728000
canvasArea = 50416
x = 0