在图像上绘制文字。

3
我正在尝试使用以下代码在图像上绘制文本:
procedure TfMain.TextToImage(const AText: string; const AImage: TImage);
begin
  if NOT Assigned(AImage) then Exit;    
  AImage.Canvas.BeginScene;
  AImage.Canvas.Font.Size    := 18;
  AImage.Canvas.Font.Family  := 'Arial';
  AImage.Canvas.Fill.Color   := TAlphaColorRec.Dodgerblue;
  AImage.Canvas.Font.Style   := [TFontStyle.fsbold];
  AImage.Canvas.FillText( AImage.AbsoluteRect,
                          AText,
                          False,
                          1,
                          [TFillTextFlag.RightToLeft],
                          TTextAlign.taCenter,
                          TTextAlign.taCenter);
  AImage.Canvas.EndScene;
end;

问:为什么上述过程在Windows上有效,但在Android上无效?


你确定 android 标签被正确地附加了吗? - azizbekian
@azizbekian 我猜是这样,你看了我的问题吗?还是只看了代码 :) - RepeatUntil
在Android中,我们可以通过自定义视图来实现这一点,并且需要添加所有想要应用于Android文本中的TTF文件。 - Chetan Joshi
2个回答

5

尝试直接在TImageTBitmap上进行绘制,而不是在TImage的Canvas上进行绘制。

在访问图像之前,您还需要创建一个位图:

AImage.Bitmap := TBitmap.Create(Round(AImage.Width), Round(AImage.Height));

因此,正确的代码将类似于以下内容:

procedure TfMain.TextToImage(const AText: string; const AImage: TImage);
begin
  if NOT Assigned(AImage) then Exit;
  AImage.Bitmap := TBitmap.Create(Round(AImage.Width), Round(AImage.Height));
  AImage.Bitmap.Canvas.BeginScene;
  try
    //....
    // Use AImage.Bitmap.Canvas as needed
    AImage.Bitmap.Canvas.FillText( AImage.AbsoluteRect,
                            AText,
                            False,
                            1,
                            [],
                            TTextAlign.Center,
                            TTextAlign.Center);
  finally
    AImage.Bitmap.Canvas.EndScene;
  end;
end;

TImage.Paint事件的代码中,你会看到:

procedure TImage.Paint;
var
  R: TRectF;
begin
  if (csDesigning in ComponentState) and not Locked and not FInPaintTo then
  begin
    R := LocalRect;
    InflateRect(R, -0.5, -0.5);
    Canvas.DrawDashRect(R, 0, 0, AllCorners, AbsoluteOpacity, $A0909090);
  end;

  UpdateCurrentBitmap;
  if FCurrentBitmap <> nil then
    DrawBitmap(Canvas, LocalRect, FCurrentBitmap, AbsoluteOpacity);
end;

无论您在画布上绘制什么,下一次重新绘制时它都会再次绘制完整的位图并擦除您已经完成的内容。
如果您不想触摸位图,则需要重写TImageOnPaint事件,并调用function TextToImage(const AText: string; const AImage: TImage);

0

以下是在Android中带有文本的ImageView的自定义类。但需要添加TTF或OTF文件以获取更多字体。

package com.fuzzydev;

import com.fuzzydev.labeledimageview.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return Dejan Ristic
 * ----------------------------------------------------------------------------
 */

public class LabeledImageView extends ImageView {

    private static final String TAG = "LabeledImageView";

    private static final int DEFAULT_TEXT_STYLE = Typeface.NORMAL;
    private static final int DEFAULT_TEXT_COLOR = Color.WHITE;
    private static final int DEFAULT_SCREEN_LOCATION = 0;
    private static final int DEFAULT_X_OFFSET = 30;
    private static final int DEFAULT_Y_OFFSET = 30;

    private static final float DEFAULT_TEXT_SIZE = 40f;

    private float textSize;
    private float xPos, yPos;
    private float xOffset, yOffset;

    private int labelLocation;
    private int textStyle;
    private int textColor;

    private String text;
    private String customFont;

    private Paint mTextPaint;

    public LabeledImageView(Context context) {
        super(context);
        initWithDefautls();
    }

    public LabeledImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initWithAttrs(attrs, context);
    }

    private void initWithDefautls() {
        textSize = DEFAULT_TEXT_SIZE;
        textStyle = DEFAULT_TEXT_STYLE;
        textColor = DEFAULT_TEXT_COLOR;
        labelLocation = DEFAULT_SCREEN_LOCATION;
        xOffset = DEFAULT_X_OFFSET;
        yOffset = DEFAULT_Y_OFFSET;
        setTextPaint();
    }

    private void initWithAttrs(AttributeSet attrs, Context context) {
        initAttrs(context, attrs);
        setTextPaint();
        if (customFont != null) {
            setCustomFont(context);
        }
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.LabeledImageView, 0, 0);

        try {
            text = a.getString(R.styleable.LabeledImageView_text);
            textSize = a.getFloat(R.styleable.LabeledImageView_textSizePx,
                    DEFAULT_TEXT_SIZE);
            textStyle = a.getInt(R.styleable.LabeledImageView_textStyle,
                    DEFAULT_TEXT_STYLE);
            textColor = a.getInt(R.styleable.LabeledImageView_textColor,
                    DEFAULT_TEXT_COLOR);
            labelLocation = a.getInt(
                    R.styleable.LabeledImageView_labelPosition,
                    DEFAULT_SCREEN_LOCATION);
            customFont = a.getString(R.styleable.LabeledImageView_customFont);
            xOffset = a.getFloat(R.styleable.LabeledImageView_xOffset,
                    DEFAULT_X_OFFSET);
            yOffset = a.getFloat(R.styleable.LabeledImageView_yOffset,
                    DEFAULT_Y_OFFSET);
            ;
        } finally {
            a.recycle();
        }
    }

    private void setCustomFont(Context ctx) {
        Typeface tf = null;
        try {
            tf = Typeface.createFromAsset(ctx.getAssets(), customFont);
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: " + e.getMessage());
        }
        mTextPaint.setTypeface(tf);
    }

    private void setLabelLocation() {

        switch (labelLocation) {
        case 0: // Top Left
            xPos = xOffset;
            yPos = yOffset;
            break;
        case 1: // Top Right
            xPos = getWidth() - mTextPaint.measureText(text) - xOffset;
            yPos = yOffset;
            break;
        case 2: // Bottom Left
            xPos = xOffset;
            yPos = getHeight() - yOffset;
            break;
        case 3: // Bottom Right
            xPos = getWidth() - mTextPaint.measureText(text) - xOffset;
            yPos = getHeight() - yOffset;
            break;
        case 4: // Top Center
            xPos = (getWidth() / 2) - (mTextPaint.measureText(text) / 2);
            yPos = yOffset;
            break;
        case 5: // Bottom Center
            xPos = (getWidth() / 2) - (mTextPaint.measureText(text) / 2);
            yPos = getHeight() - yOffset;
            break;
        case 6: // Center
            xPos = (getWidth() / 2) - (mTextPaint.measureText(text) / 2);
            yPos = (getHeight() / 2);
        default:
            break;
        }
    }

    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        setLabelLocation();
    }

    private void setTextPaint() {
        mTextPaint = new Paint();
        mTextPaint.setTextSize(textSize);
        mTextPaint.setColor(textColor);
        mTextPaint.setTypeface(Typeface.defaultFromStyle(textStyle));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (text != null) {
            canvas.drawText(text, xPos, yPos, mTextPaint);
        }
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public void setCustomFont(String customFont) {
        this.customFont = customFont;
    }

    public void setLabelLocation(int labelLocation) {
        this.labelLocation = labelLocation;
    }

    public void setyOffset(float yOffset) {
        this.yOffset = yOffset;
    }

    public void setxOffset(float xOffset) {
        this.xOffset = xOffset;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setTextStyle(int textStyle) {
        this.textStyle = textStyle;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }
}

请见上述类的实现 在此处

https://github.com/DejanRistic/LabeledImageView/tree/master/src/com/fuzzydev

链接


1
这段代码看起来像 Delphi 代码吗?问题明确标记为 Delphi,因此 Java 解决方案并没有太大帮助。 - Ken White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接