如何查找相对文本大小

问题描述 投票:0回答:1

我试图在不同大小的图像上绘制文本。图像以ImageView显示,然后在Canvas上绘制。虽然Canvas保留了图像的原始高度和宽度,但ImageView中的图像确实显得更小,因此这使得为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行计算ImageViewCanvas的面积。第三行基本上将它们放在一起并且(理想情况下)输出一个浮点值,该浮点值是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个不同尺寸的图片,看看每个图片的文字大小。以下是我的发现:

  1. 274 x 184 topTextSize:0,bottomTextSize:0
  2. 3704 x 2469 topTextSize:237.58,bottomTextSize:237.58
  3. 640 x 480 topTextSize:0,bottomTextSize:0
  4. 2560 x 1920 topTextSize:168,bottomTextSize:168

对于24,只有顶部文本显示在位图上

例如,以下是尺寸为274 x 184的图像的值:

textSize = 168
imageViewArea = 1728000
canvasArea = 50416
x = 0
java android algorithm math android-canvas
1个回答
1
投票

您计算的比率是面积比率,而不是长度比率。如果您沿着每一侧缩放图像2,您将获得4的面积比(或1/4,具体取决于您考虑的方向)。字体大小应该是长度,因此您应该使用长度比。

如果您知道缩放是均匀的(高度与宽度相同),则只需根据宽度或高度(而不是区域)计算比率。如果不是,则需要一种可以在一个方向上拉伸字体的文本渲染方法。如果你想使用保留面积比的某种平均字体大小,只需使用x = textSize * sqrt(canvasArea / imageViewArea)

偏离主题的评论:您的代码段中有很多不必要的括号。就个人而言,我认为这使得阅读代码变得更加困难。因此,我建议删除不必要的括号(除非故意使用它们来表达某种含义)。

© www.soinside.com 2019 - 2024. All rights reserved.