如何在图片中插入交互文本?

blfriend_2000 2005-01-04 09:37:57
就是实现好像photoshop那样的插入文本功能,文本插入以后,通过鼠标的选择能够移动位置,进行编辑等~~~~~~

我现在用brush 只能做到在特定位置插入栅格化了的文字,根本就不能再编辑~~~~~

请高手帮帮忙
...全文
199 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
linzhengqun 2005-01-05
  • 打赏
  • 举报
回复
、、、、、、、、、、、、、、、、、、、、
测试单元:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, TFlatMemoUnit,UEdtFont,uFontEdit;

type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
EdtFont:TFontEdit;
// C:TCanvas;
public
{ Public declarations }
isDown:Boolean;
hasMove:Boolean;
OrgP,prevP,offSetP:TPoint;
hasDone:Boolean;
c:TCanvas;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then
begin
isDown:=true;
hasMove:=false;
orgP:=Point(X,Y);
offsetP:=Point(X,Y);
self.Canvas.Rectangle(Rect(orgP,offsetP));
end;
if hasDone and assigned(EdtFont) then
begin
FreeAndNil(EdtFont);
hasDone:=false;
end;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if isDown then
begin
hasMove:=True;
self.Canvas.Rectangle(Rect(orgP,offsetP));
offsetP:=Point(X,Y);
self.Canvas.Rectangle(Rect(orgP,offsetP));
end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
self.Canvas.Rectangle(Rect(orgP,offsetP));
isDown:=false;
hasDone:=true;
if hasMove then
begin
EdtFont:=TFontEdit.Create(self,self.Font);
EdtFont.Visible:=false;
EdtFont.Parent:=self;
EdtFont.Font:=Font;
EdtFont.Left:=OrgP.X;
EdtFont.Top:=OrgP.Y;
EdtFont.Width:=offsetP.X-OrgP.X;
EdtFont.Height:=offsetP.Y-OrgP.Y;
EdtFont.Visible:=true;
end
else
begin
EdtFont:=TFontEdit.Create(self,self.Font);
EdtFont.Visible:=false;
EdtFont.Parent:=self;
EdtFont.Font:=Font;
EdtFont.Left:=OrgP.X;
EdtFont.Top:=OrgP.Y;
EdtFont.Visible:=true;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
self.Canvas.Pen.Style:=psDash;
self.Canvas.Pen.Mode:=pmNot;
self.Canvas.Brush.Style:=bsClear;
self.DoubleBuffered:=true;
end;

end.
把上面的代码拷到程序上,再仔细看看吧。
linzhengqun 2005-01-05
  • 打赏
  • 举报
回复
你看看Windows的画图小程序,它的输入文字的功能,其实就是一个Edit,输入完毕后,再把这些文字画到画布上面的
你也完全可以这样实现之,这里有一个类,参考一下:
unit UFontEdit;

interface
uses Messages,Windows,Classes,StdCtrls,Controls,Graphics,Dialogs,Forms;
type
TFontEdit=class(TCustomMemo)
private
FFontHeight:integer;
canMove:Boolean;
MoveSize:integer;
procedure ManipulateControl(WinControl: TWinControl; Shift: TShiftState;
X, Y: integer);
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
protected
procedure CreateWnd; override;
//鼠标事件处理
procedure FontEditMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FontEditMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FontEditChange(Sender: TObject);
procedure FontEditResize(Sender:TObject);
function isInClient(X,Y:integer):Boolean;
function GetTextHeight(Font:TFont):Integer;
public
Constructor Create(AOwner:TComponent;Font:TFont);
property Color;
property Enabled;
property Font;
property Lines;
property ShowHint;
property Visible;
property OnClick;
property OnDblClick;
property OnEnter;
property OnExit;
end;

implementation

{ TFontEdit }
//移动和拉动编辑框的方法
procedure TFontEdit.ManipulateControl(WinControl: TWinControl; Shift: TShiftState;
X, Y: integer);
var SC_MANIPULATE: Word; isCan:Boolean;
begin
WinControl.Cursor := crDefault;
SC_MANIPULATE:=0;
isCan:=False;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最左侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (X<=MoveSize) and (Y>MoveSize) and (Y<WinControl.Height-MoveSize)
then begin
SC_MANIPULATE := $F001;
WinControl.Cursor := crSizeWE;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最右侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=WinControl.Width-MoveSize) and (Y>MoveSize) and (Y<WinControl.Height-MoveSize)
then begin
SC_MANIPULATE := $F002;
WinControl.Cursor := crSizeWE;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最上侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>MoveSize) and (X<WinControl.Width-MoveSize) and (Y<=MoveSize)
then begin
SC_MANIPULATE := $F003;
WinControl.Cursor := crSizeNS;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=MoveSize) and (Y<=MoveSize)
then begin
SC_MANIPULATE := $F009;
WinControl.Cursor := crSizeAll;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=WinControl.Width-MoveSize) and (Y<=MoveSize)
then begin
SC_MANIPULATE := $F005;
WinControl.Cursor := crSizeNESW;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最下侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>MoveSize) and (X<WinControl.Width-MoveSize) and (Y>=WinControl.Height-MoveSize)
then begin
SC_MANIPULATE := $F006;
WinControl.Cursor := crSizeNS;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=MoveSize) and (Y>=WinControl.Height-MoveSize)
then begin
SC_MANIPULATE := $F007;
WinControl.Cursor := crSizeNESW;
isCan:=True;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=WinControl.Width-MoveSize) and (Y>=WinControl.Height-MoveSize)
then begin
SC_MANIPULATE := $F008;
WinControl.Cursor := crSizeNWSE;
isCan:=True;
end;
if (Shift=[ssLeft])and(isCan=True)and(CanMove=true)then
begin
ReleaseCapture;
WinControl.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
end;
end;
//初始化参数
constructor TFontEdit.Create(AOwner: TComponent;Font:TFont);
begin
inherited Create(AOwner);
self.OnMouseMove:=FontEditMouseMove;
self.OnMouseDown:=FontEditMouseDown;
self.OnChange:=FontEditChange;
self.OnResize:=FontEditResize;
FFontHeight:=GetTextHeight(Font);
self.Height:=FFontHeight+2;
self.Width:=60;
MoveSize:=3;
end;
//设置编辑框的风格
procedure TFontEdit.CreateWnd;
begin
inherited;
self.Ctl3D:=false;
self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
self.Constraints.MinWidth:=60;
end;
//鼠标移动消息
procedure TFontEdit.FontEditMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
ManipulateControl(self,Shift,X,Y);
end;
//判断鼠标是否在可移动范围内
procedure TFontEdit.FontEditMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if isInClient(X,Y) then
canMove:=false
else
canMove:=true;
end;
//判断鼠标是否在客户区内
function TFontEdit.isInClient(X,Y:Integer): Boolean;
begin
result:=false;
if (X>MoveSize)and(X<self.Width-MoveSize)
and(Y>MoveSize)and (Y<self.Height-MoveSize) then
result:=true;
end;
//取得一行文本的高度
function TFontEdit.GetTextHeight(Font:TFont): Integer;
var C:TCanvas; size:Tsize;
begin
result:=0;
C:=TCanvas.Create;
C.Handle:=GetDC(Application.Handle);
try
C.Font:=Font;
if GetTextExtentPoint32(C.Handle,'H',1,size)then
result:=size.cy;
finally
C.Free;
end;
end;
//文本改变时调整最小高度
procedure TFontEdit.FontEditChange(Sender: TObject);
begin
self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
end;
//当字体被改变时调用
procedure TFontEdit.CMFontChanged(var Message: TMessage);
begin
inherited;
FFontHeight:=GetTextHeight(self.Font);
self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
end;
//当改变大小时,调整最小高度
procedure TFontEdit.FontEditResize(Sender: TObject);
begin
self.Constraints.MinHeight:=FFontHeight*(self.Lines.Count+1)+2;
end;

end.
blfriend_2000 2005-01-05
  • 打赏
  • 举报
回复
postmessage(...)不是消息传递吗?我糊涂了~~~~~~~

能不能讲的具体一点呢?我还是看不懂~~~~不好意思啊,新手~~~~
海天候 2005-01-05
  • 打赏
  • 举报
回复
做个label+edit的功能就成.
移动可以postmessage(...)具体查下panel的鼠标移动.
点击时显示edit,移开或双击显示label.移动时可以移动label.

然后输出的时候再Copy一下窗体就成:P

有点取巧的方法了,不过很简单,想想就明白,标签和edit都要程序来创建哦
blfriend_2000 2005-01-05
  • 打赏
  • 举报
回复
那尽管]多了一个Tcanvas层也不能达到随意编辑的功能阿~~~~

你怎么是那个canvas在运行后随意移动呢?怎么编辑上面的栅格化的文本呢?
vpoor 2005-01-05
  • 打赏
  • 举报
回复
photoshop使用了层的概念
换用DELPHI的说法就是它操作的是两个Tcanvas
blfriend_2000 2005-01-05
  • 打赏
  • 举报
回复
非常谢谢楼上的帮助~~~~~不过你的程序有一个小毛病:hasMove在设为True以后就一直没有改变了。

anyway~~~~thx~~

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧