首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi graphics32文本层

Delphi graphics32文本层
EN

Stack Overflow用户
提问于 2015-01-20 02:10:52
回答 1查看 1.5K关注 0票数 0

我正试图为我的图像编辑应用程序创建一个textTool,所以我在主表单上有一个按钮,上面写着"Text tool“。当我单击它时,一个新的表单(模式)显示,允许我选择一个字体并在RichEdit中输入一个文本。

我的想法是让用户在RichEdit中格式化他的文本,当他满意的时候,他应该点击模态按钮,文本(格式化的)将插入到我的图像的一个新的层中。另外,我的想法是将文本作为文本行处理,并在新的Bitmap32中分别呈现它们,然后将获得的位图分配给新层。

为此,我使用这个函数

代码语言:javascript
复制
function GetTextWidth(const Text: string; const Font: TFont): Integer;
var
  Canvas: TCanvas;
begin
  Canvas := TCanvas.Create;
  try
    Canvas.Handle := GetDC(0);
    try
      Canvas.Font.Assign(Font);
      Result := Canvas.TextWidth(Text);
    finally
      ReleaseDC(0, Canvas.Handle);
    end;
  finally
    Canvas.Free;
  end;
end;

并解析richedit的行并获得每个行的textWidth,如下所示:

代码语言:javascript
复制
    for q := 0 to TextEditor.RichEdit1.Lines.Count-1 do
    begin
      latime:=GetTextWidth(TextEditor.RichEdit1.Lines[q], TextEditor.RichEdit1.Font);
      Memo1.Lines.Add('Text row '+IntToStr(q)+' width='+IntToStr(latime));
    end;

因此,我将很容易地获得最大的宽度线(最大宽度),我打算使用它来生成我的Bitmap32。

因此,对于我的Bitmap32,我使用了以下代码(它不显示任何不幸的东西)

代码语言:javascript
复制
// generating the Bitmap32  to place text on it
    tmp := TBitmap32.Create;
    tmp.SetSize(maxwidth, textLineHeight*TextLineCount);
    for q := 0 to textLineCount-1 do
    begin
      tmp.RenderText(maxwidth,textLineHeight,TextEditor.RichEdit1.Lines[q],1,myFont.Color);
        Memo1.Lines.Add('rendering line of text:'+TextEditor.RichEdit1.Lines[q]);
    end;

// Generating the text layer
    B := TBitmapLayer.Create(ImgView.Layers);
// Assigning the 'written' bitmap to the new layer
    B.Bitmap.Assign(tmp);
    B.Bitmap.DrawMode:=dmBlend;

// Positioning 
    with ImgView.GetViewportRect do
        P := ImgView.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));

// Sizing the layer
    B.Location:=GR32.FloatRect(P.X - maxwidth, P.Y - textLineHeight, P.X + maxwidth, P.Y + textLineHeight);

// displaying the new text layer
    imgView.Invalidate;

所以我没有错误,但是新的图层没有显示.好像什么都没发生一样。

我尝试使用固定的宽度和高度值(我使用了200 bor两者),但是我的ImageView上仍然什么也没有出现,所以我假设可能是位置有问题吗?

请帮助我解决这个问题。

非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-20 16:28:41

首先,任何高级格式(以RichEdit提供的扩展功能形式)都不受RenderText函数的支持。它只是将具有位图字体属性属性的字符串(按原样)输出到某个特定位置(在您的示例中,位置为maxwidth / textLineHeight)。

为了解决这个问题,我从一个更简单的代码开始。类似于:

代码语言:javascript
复制
B := TBitmapLayer.Create(ImgView.Layers);
B.Location := FloatRect(0, 0, 100, 100);
B.Bitmap.SetSize(100, 100);
B.Bitmap.RenderText(0, 0, 'Test', 1, clBlack32);
B.Bitmap.DrawMode := dmBlend;

请注意,clBlack32用作颜色,而不是clBlack,因为后者不包含有关透明度的信息。您使用的颜色(在myFont.Color中)可能是TColor类型(而不是TColor32类型)。如果是TColor (如clBlack ),则它的alpha值为0,等于完全透明。

此代码应将文本“Test”绘制到左上角位置。如果您没有看到文本,您可以添加以下内容

代码语言:javascript
复制
B.Bitmap.Clear(clRed32);

在SetSize电话之后。这样,图层的位图背景色将被设置为红色。因此,您应该能够更容易地发现层的边界。

一旦文本显示在屏幕上,您可以通过显示多行文本、调整x/y位置等进一步移动,直到您的代码看起来像上面发布的代码为止。

几点意见:

通过调整图层的大小,使其与位图尺寸不同,文本将被拉伸。这可能看起来很奇怪,文本可能会呈现不可读性。最终,您可能希望在调整图层大小之后刷新位图上的文本。

函数RenderText(…)如果AALevel (过采样因子)较高,则会产生更平滑的输出。但是,函数调用越慢,值越高。这个比例更大或者是二次的,这意味着如果你把调用的值增加一倍,调用速度至少会慢4倍。实际上,一旦超过了处理器的缓存,速度就会更慢。在这种情况下,你将面临严重的性能下降。

此外,文本的宽度将得到准确的。在最坏的情况下,它可以是(2^AALevel * Length(string))像素!

最后,最好在v2.0中使用新矢量引擎的文本呈现功能。虽然这些步骤不像相当简单的RenderText(.)那样笔直调用,输出看起来更令人愉快,而且与高AALevel输出相比要快得多。此外,TextWidth也可以以一种完全准确的方式确定。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28036681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档