siwangqishiq / ImageEditor-Android

AndroidImageEdit 安卓设备上图形编辑开源控件,支持磨皮美白 自定义贴图 图片滤镜 图片旋转 图片剪裁 文字贴图 撤销 回退 等操作
2.19k stars 567 forks source link

关于文字居中显示和自动换行问题 #43

Closed taoze closed 6 years ago

taoze commented 6 years ago

发现文字没有居中显示,请问一下作者,怎么实现文字在背景框中居中显示?还有那个自动换行功能该如何实现啊?作者是不是可以把这些功能优先完善一下,让我等屌丝好好参考学习一下哈~

siwangqishiq commented 6 years ago

背景框中居中显示 是指换行的时候 比较短的文字没有居中的意思?

taoze commented 6 years ago

输入文本的时候,无论是单行文字还是多行文字,文字都没有在背景框的正中间,上下边距不一致,左右边距不一致,这个应该怎么处理呢?

siwangqishiq commented 6 years ago

文字在背景框里不居中 我这里并没有发现这个问题 如果有 可能是部分字符大小不一样导致的. 自动换行的功能 目前看来实现起来较为复杂 需要考虑总体控件的大小 缩放文字对换行的影响 ,以后有时间会考虑实现

taoze commented 6 years ago

demo中文字确实没有居中显示,不仅仅是因为部分字符大小不一致原因导致的,作者也许没有太在意drawText(String text, float x,float y,Paint paint)方法中x和y所正在代表的含义,它不是绘制文字中心的坐标,我给你附一张图吧,希望对作者有所帮助,同时也期待作者早日更新下个版本,实现文字自动换行功能,谢谢~ drawtext

siwangqishiq commented 6 years ago

好的~因为这块代码是当时根据图片贴图功能直接修改的 的确没有注意到文字和图片的区别, 但是因为背景框画的只是辅助线 并不会在最终的生成图片上表现出来 所以奇怪为什么你要严格要求这个文字居中?

siwangqishiq commented 6 years ago

坐标问题 已做微调

Qdafengzi commented 8 months ago

我已经 画对位置了 贴代码 Kotlin的版本,希望可以帮助有些人 关键:Baseline

private fun drawText(canvas: Canvas, _x: Int, _y: Int, scale: Float, rotate: Float) {
        if (mTextContents.isEmpty()) return
        var x = _x
        var y = _y
        val textHeight: Int
        //clear
        mTextRect.setEmpty()
        val tempRect = Rect()
        val fontMetrics = mPaint.fontMetrics
        val charMinHeight0 = mPaint.getFontMetrics(fontMetrics)
        //要找的基线位置 绘制的起点位置
        val paintBaseline = abs(fontMetrics.top)
        val charMinHeight = getHeightWithFontPadding(mPaint)
        textHeight = charMinHeight.toInt()
        var totalHeight = 0
        var maxWidth = 0
        //System.out.println("top = "+fontMetrics.top +"   bottom = "+fontMetrics.bottom);

        mTextContents.forEach { text ->
            val width = mPaint.measureText(text?:"")
            mPaint.getTextBounds(text, 0, (text ?: "").length, tempRect)
            //System.out.println(i + " ---> " + tempRect.height());
            //text_height = Math.max(charMinHeight, tempRect.height());
            if (tempRect.height() <= 0) { //处理此行文字为空的情况
                tempRect.set(0, 0, 0, textHeight)
            }

            //计算出来总高度
            totalHeight += textHeight
            if (width > maxWidth) {
                maxWidth = width.toInt()
            }
            RectUtil.rectAddV(mTextRect, tempRect, 0, charMinHeight.toInt())
        }
        x -= maxWidth / 2
        y -= totalHeight / 2
        mTextRect.offset(x, y)

        mHelpBoxRect.set(
            (mTextRect.left - PADDING).toFloat(),
            (mTextRect.top - PADDING).toFloat(),
            (mTextRect.right + PADDING).toFloat(),
            (mTextRect.bottom + PADDING).toFloat()
        );
        RectUtil.scaleRect(mHelpBoxRect, scale)
        canvas.save()
        canvas.scale(scale, scale, mHelpBoxRect.centerX(), mHelpBoxRect.centerY())
        canvas.rotate(rotate, mHelpBoxRect.centerX(), mHelpBoxRect.centerY())

        //baseline是文本绘制的起始位置,向上为负数,向下为正数。
        var drawTextY = y + paintBaseline

        mTextContents.forEach {
            val alignX: Int = when (mPaint.textAlign?: Paint.Align.CENTER) {
                Paint.Align.CENTER -> ((mTextRect.left + mTextRect.right) / 2)
                Paint.Align.RIGHT -> mTextRect.right
                Paint.Align.LEFT -> mTextRect.left
            }
            canvas.drawText(it ?: "", alignX.toFloat(), drawTextY, mPaint)
            drawTextY += textHeight
        }

//        canvas.drawCircle(canvas.getWidth(),canvas.getHeight(),20f,mPaint);
//        canvas.drawLine(canvas.width/2f,0f,canvas.width /2f, canvas.height.toFloat(),mPaint);
//        canvas.drawLine(0f,canvas.height /2f, canvas.width.toFloat(), (canvas.height /2).toFloat(),mPaint);
        canvas.restore()
    }

       fun getHeightWithFontPadding(paint: Paint): Float {
        val fm = paint.fontMetrics
        return fm.bottom - fm.top + fm.leading
    }