黄聪:一个拼图工具的制作思路

简介:

测试简图:



功能简介:
1、双击左窗口可打开源图像;
2、框选左窗口可把图像选取复制到右窗口;
3、剪取的图块可以移动, 可配合 Ctrl 单选或多选, 可用 Delete 删除选择的图块;
4、双击右窗口可保存拼好的图像.



功能实现:
1、MoveImage 主要完成 "图块" 的功能;
2、ImageBox 主要完成源图像及选取功能;
3、其他有主模块 Unit1 完成.



窗体:


object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 350
ClientWidth = 671
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
OnKeyUp = FormKeyUp
PixelsPerInch = 96
TextHeight = 13
object Splitter1: TSplitter
Left = 361
Top = 0
Height = 350
ExplicitLeft = 272
ExplicitTop = 128
ExplicitHeight = 100
end
object ScrollBox1: TScrollBox
Left = 0
Top = 0
Width = 361
Height = 350
Align = alLeft
TabOrder = 0
OnClick = ScrollBox1Click
OnDblClick = ScrollBox1DblClick
ExplicitHeight = 328
object Image1: TImage
Left = 3
Top = 3
Width = 25
Height = 25
OnMouseEnter = Image1MouseEnter
end
end
end


Unit1:


unitUnit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ExtDlgs, MoveImage, ImageBox;

type
TForm1 = class(TForm)
ScrollBox1: TScrollBox;
Splitter1: TSplitter;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Image1MouseEnter(Sender: TObject);
procedure ScrollBox1Click(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure ScrollBox1DblClick(Sender: TObject);
end;

var
Form1: TForm1;
ImageBox1: TImageBox;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ImageBox1 := TImageBox.Create(Self);
with ImageBox1 do begin
Parent := Self;
Align := alClient;
OutImage := Image1;
end;
ScrollBox1.Color := clWhite;
ScrollBox1.DoubleBuffered := True;
KeyPreview := True;
List := TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
i: Integer;
begin
for i := 0 to List.Count - 1 do TMoveImage(List[i]).Free;
List.Free;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
i: Integer;
begin
if Key = VK_DELETE then for i := List.Count - 1 downto 0 do
if TMoveImage(List[i]).Selected then
begin
TMoveImage(List[i]).Free;
List.Delete(i);
end;
end;

procedure TForm1.Image1MouseEnter(Sender: TObject);
var
mi: TMoveImage;
begin
Image1.Visible := False;
mi := TMoveImage.Create(ScrollBox1);
with mi do begin
Parent := ScrollBox1;
Left := Image1.Left;
Top := Image1.Top;
Width := Image1.Width;
Height := Image1.Height;
Picture.Bitmap.Assign(Image1.Picture.Bitmap);
end;
List.Add(mi);
end;

procedure TForm1.ScrollBox1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to List.Count - 1 do
TMoveImage(List[i]).Selected := False;
end;

procedure TForm1.ScrollBox1DblClick(Sender: TObject);
var
i: Integer;
begin
with TSavePictureDialog.Create(nildo if Execute then
begin
with TBitmap.Create do
begin
Width := ScrollBox1.HorzScrollBar.Range + 20;
Height := ScrollBox1.VertScrollBar.Range + 20;
for i := 0 to List.Count - 1 do
begin
TMoveImage(List[i]).Selected := False;
Canvas.Draw(TMoveImage(List[i]).Left,
TMoveImage(List[i]).Top,
TMoveImage(List[i]).Picture.Bitmap);
end;
SaveToFile(FileName);
Free;
end;
Free;
end;
end;

end.



ImageBox:


unitImageBox;

interface

uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls, ExtDlgs;

type
TImageBox = class(TScrollBox)
private
FImage: TImage;
FShape: TShape;
FBitmap: TBitmap;
FFlag: Boolean;
FOutImage: TImage;
procedure SetOutImage(const Value: TImage);
protected
procedure ImageBoxDblClick(Sender: TObject);
procedure ImageBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X: Integer; Y: Integer);
procedure ImageBoxMouseMove(Sender: TObject; Shift: TShiftState;
X: Integer; Y: Integer);
procedure ImageBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X: Integer; Y: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Bitmap: TBitmap read FBitmap;
property OutImage: TImage read FOutImage write SetOutImage;
published
end;

implementation

{ TImageBox }

constructor TImageBox.Create(AOwner: TComponent);
begin
inherited;
OnDblClick := ImageBoxDblClick;
OnMouseDown := ImageBoxMouseDown;
OnMouseMove := ImageBoxMouseMove;
OnMouseUp := ImageBoxMouseUp;

FImage := TImage.Create(Self);
FImage.Parent := Self;
FImage.AutoSize := True;
FImage.OnDblClick := OnDblClick;
FImage.OnMouseDown := ImageBoxMouseDown;
FImage.OnMouseMove := ImageBoxMouseMove;
FImage.OnMouseUp := ImageBoxMouseUp;

FShape := TShape.Create(Self);
FShape.Parent := Self;
FShape.Brush.Style := bsClear;
FShape.Pen.Style := psDot;
FShape.BoundsRect := Rect(0000);
FShape.BringToFront;

FBitmap := TBitmap.Create;
end;

procedure TImageBox.ImageBoxDblClick(Sender: TObject);
begin
FFlag := False;
with TOpenPictureDialog.Create(nildo if Execute then
begin
FImage.Picture.LoadFromFile(FileName);
Free;
end;
end;

destructor TImageBox.Destroy;
begin
FImage.Free;
FShape.Free;
FBitmap.Free;
inherited;
end;

procedure TImageBox.ImageBoxMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
cx,cy: Integer;
begin
FFlag := True;
cx := X - HorzScrollBar.Position;
cy := Y - VertScrollBar.Position;
FShape.BoundsRect := Rect(cx, cy, cx, cy);
end;

procedure TImageBox.ImageBoxMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
var
cx,cy: Integer;
begin
if FFlag then
begin
cx := X - HorzScrollBar.Position;
cy := Y - VertScrollBar.Position;
if FFlag then FShape.BoundsRect := Rect(FShape.Left, FShape.Top, cx, cy);
end else
FShape.BoundsRect := Rect(0000);
end;

procedure TImageBox.ImageBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
R: TRect;
begin
if not FFlag then Exit;
FFlag := False;
if FShape.Width * FShape.Height < 100 then Exit;

if FShape.Width < 0 then
begin
FShape.Left := FShape.Left + FShape.Width;
FShape.Width := -FShape.Width;
end;
if FShape.Height < 0 then
begin
FShape.Top := FShape.Top + FShape.Height;
FShape.Height := -FShape.Height;
end;
FBitmap.Width := FShape.Width;
FBitmap.Height := FShape.Height;
R := FShape.BoundsRect;
OffsetRect(R, HorzScrollBar.Position, VertScrollBar.Position);
FBitmap.Canvas.CopyRect(FShape.ClientRect, FImage.Canvas, R);
if Assigned(FOutImage) then with FOutImage do
begin
AutoSize := True;
Picture.Bitmap.Assign(FBitmap);
Left := (Parent.ClientWidth - FOutImage.Width) div 2;
Top := (Parent.ClientHeight - Height) div 2;
Visible := True;
end;
end;

procedure TImageBox.SetOutImage(const Value: TImage);
begin
FOutImage := Value;
end;

end.



MoveImage:


unitMoveImage;

interface

uses
Windows, Classes, Graphics, Controls, ExtCtrls;

type
TMoveImage = class(TImage)
private
FFlag: Boolean;
FX,FY: Integer;
FSelected: Boolean;
procedure SetSelected(const Value: Boolean);
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer;
Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X: Integer; Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X: Integer;
Y: Integer); override;
public
constructor Create(AOwner: TComponent); override;
property Selected: Boolean read FSelected write SetSelected;
end;

var
List: TList;

implementation

{ TMoveImage }

constructor TMoveImage.Create(AOwner: TComponent);
begin
inherited;
Parent := TWinControl(AOwner);
Left := (TWinControl(AOwner).ClientWidth - Width) div 2;
Top := (TWinControl(AOwner).ClientHeight - Height) div 2;
end;

procedure TMoveImage.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
inherited;
FFlag := True;
FX := X;
FY := Y;
Selected := True;
end;

procedure TMoveImage.MouseMove(Shift: TShiftState; X, Y: Integer);
var
i: Integer;
begin
inherited;
if FFlag then
begin
Left := Left + X - FX;
Top := Top + Y - FY;
for i := 0 to List.Count - 1 do
if (TMoveImage(List[i]) <> Self) and (TMoveImage(List[i]).Selected) then
begin
TMoveImage(List[i]).Left := TMoveImage(List[i]).Left + X - FX;
TMoveImage(List[i]).Top := TMoveImage(List[i]).Top + Y - FY;
end;
end;
end;

procedure TMoveImage.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
inherited;
FFlag := False;
if not (ssCtrl in Shift) then
Selected := False;
end;

procedure TMoveImage.SetSelected(const Value: Boolean);
var
bit: TBitmap;
begin
if Value <> FSelected then
begin
FSelected := Value;
bit := TBitmap.Create;
bit.Width := Width;
bit.Height := Height;
BitBlt(Canvas.Handle, 00, Width, Height, bit.Canvas.Handle, 00, SRCINVERT);
Repaint;
bit.Free;
end;
end;

end.




本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/08/27/1810014.html,如需转载请自行联系原作者
相关文章
|
6天前
|
小程序 vr&ar
如何用一张二维码展示图文并茂的产品画册?内附详细制作教程!
使用草料二维码可以将所有产品整合到一个二维码中,形成电子画册,适用于展会和拓客。客户微信扫码即可查看产品视频、VR全景等,操作简单且便于分享。内容实时更新,确保客户获取最新资料,显著提升销售效率。搭建方便,模板库提供产品目录模板,按需修改后生成二维码即可使用。
|
5月前
|
vr&ar
简单易懂的 全景图高清下载方法以及原理简要解析(支持下载建E、720yun、酷雷曼、景站、酷家乐、百度街景原图)
这篇文章介绍了一种简单易懂的全景图高清下载方法,使用在线网站全景管家,支持下载包括建E、720yun、酷雷曼等多个平台的全景图原图,并简要解析了全景图的原理和制作方法。
简单易懂的 全景图高清下载方法以及原理简要解析(支持下载建E、720yun、酷雷曼、景站、酷家乐、百度街景原图)
|
8月前
|
缓存 前端开发 搜索推荐
博客有点丑,魔改优化来一波🛠️
博客有点丑,魔改优化来一波🛠️
132 1
|
8月前
微信小游戏制作工具关于游戏屏幕适配,看这篇就够了!
微信小游戏制作工具关于游戏屏幕适配,看这篇就够了!
275 0
|
存储 Shell 开发工具
!!!如何解决使用hexo 博客上无法正常显示图片的问题【亲测可行,无脑简单,快捷省力】
!!!如何解决使用hexo 博客上无法正常显示图片的问题【亲测可行,无脑简单,快捷省力】
!!!如何解决使用hexo 博客上无法正常显示图片的问题【亲测可行,无脑简单,快捷省力】
|
Web App开发 编解码 安全
⭐程序员必备软件图鉴⭐(建议收藏)
⭐程序员必备软件图鉴⭐(建议收藏)
⭐程序员必备软件图鉴⭐(建议收藏)
|
小程序 API Android开发
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
178 0
小程序开发-第三章第四节点击查看大图,保存壁纸-全栈工程师之路-中级篇
|
vr&ar 图形学 索引
【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景
|
搜索推荐 图形学 UED
听说C站还有人缺图片素材?一篇跟UI设计师要来的——图片网址整理大全 让你从此远离素材荒!(强烈建议收藏)
目录 📢前言 😀听说C站还有人缺图片素材?一篇跟UI设计师求来的——图片网址整理大全 让你从此远离素材荒! 🍓图标设计必备网 🍈优质图库必备网 🍍设计神器 🌽综合性设计网站 🍏插画必备 🍒字体网站 🍑UI设计师 🥥10个设计师常用免费商用图片网站: 🥝制作自己的网格纸 🥑配色神器网站 🍉设计师的视野必备 🥭常用素材网站: 🍈配色类 🍇原型设计类 🍋导航类 🍊服装类 🍅时尚街拍 🍆纹理材质 🍌配色网站 🥔其他更多 🍤综合系列精品网址 👥总结
听说C站还有人缺图片素材?一篇跟UI设计师要来的——图片网址整理大全 让你从此远离素材荒!(强烈建议收藏)