如何找到相对文字大小

时间:2019-03-23 05:27:55

标签: java android algorithm math android-canvas

我正在尝试在尺寸不同的图像上绘制文本。图像显示在ImageView中,然后绘制在Canvas上。虽然Canvas保留了图像的原始高度和宽度,但是图像在ImageView中的确显得小很多,因此这使得为Canvas选择合适的文本大小非常繁琐,因为{ {1}}对文本在图像上的显示方式有误解。

为解决此问题,我决定使用交叉乘法为ImageView上的文本找到合适的文本大小,假定该文本大小像在Canvas上一样出现在{ {1}}。这是我的尝试:

Canvas

第一行获取出现在ImageView上的文本的大小。第二和第三行计算textSize = topTextView.getTextSize(); imageViewArea = ((img.getWidth()) * (img.getHeight())); canvasArea = ((canvas.getWidth()) * (canvas.getHeight())); x = (((textSize)/(imageViewArea)) * (canvasArea)); ImageView的面积。第三行基本上将所有内容放在一起,并(理想情况下)输出一个浮点值,该值应为在ImageView上绘制的文本的大小。

但是,它并没有达到应有的水平。在小图像上绘制文字时,文字难以理解。在中型图像上绘制时薄而丑。基本上,它看起来与预览中的外观不同。

我的假设是:交叉乘法不是要走的路。

有什么建议吗?

Canvas

输出

因此,我上传了4张不同尺寸的图片,以查看每张图片的文字大小。这是我的发现:

  1. Canvas topTextSize:0,bottomTextSize:0
  2. 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; } topTextSize:237.58,bottomTextSize:237.58
  3. 274 x 184 topTextSize:0,bottomTextSize:0
  4. 3704 x 2469 topTextSize:168,bottomTextSize:168

对于640 x 4802560 x 1920,只有最上面的文本显示在位图上

例如,以下是尺寸为2的图像的值:

4

1 个答案:

答案 0 :(得分:1)

您计算的比率是面积比率,而不是长度比率。如果将图像的每一边按2比例缩放,则面积比将为4(或1/4,取决于所考虑的方向)。字体大小应为长度,因此应使用长度比例。

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

离题注释:您的代码片段中有很多不必要的括号。我个人认为这会使阅读代码更加困难。因此,我建议删除不必要的括号(除非故意使用括号来传达某些含义)。