测试简图:


功能简介:
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 = 13object Splitter1: TSplitter
Left = 361
Top = 0
Height = 350
ExplicitLeft = 272
ExplicitTop = 128
ExplicitHeight = 100endobject ScrollBox1: TScrollBox
Left = 0
Top = 0
Width = 361
Height = 350
Align = alLeft
TabOrder = 0
OnClick = ScrollBox1Click
OnDblClick = ScrollBox1DblClick
ExplicitHeight = 328object Image1: TImage
Left = 3
Top = 3
Width = 25
Height = 25
OnMouseEnter = Image1MouseEnterendendend

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(0, 0, 0, 0);
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(0, 0, 0, 0);
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, 0, 0, Width, Height, bit.Canvas.Handle, 0, 0, SRCINVERT);
Repaint;
bit.Free;
end;
end;

end.

本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/08/27/1810014.html,如需转载请自行联系原作者

黄聪:一个拼图工具的制作思路相关推荐

  1. 每日自动签到工具的制作思路

    背景 很多网站和app都使用签到的方式来增加用户的黏度和活跃度,每次给一点小奖励.这的确是个有效的方式.于是就想,能不能做一个自动签到的工具,直接放服务器上,定时执行,这样就不用自己每天去打开网站进行 ...

  2. python写一个ssh工具_Python3制作简易SSH登录工具|python3教程|python入门|python教程

    https://www.xin3721.com/eschool/pythonxin3721/ 本文转载至知乎ID:Charles(白露未晞)知乎个人专栏 下载W3Cschool手机App,0基础随时随 ...

  3. 用java做一个截图工具_Java制作屏幕截图软件(还可以保存到剪切板内)

    原标题:Java制作屏幕截图软件(还可以保存到剪切板内) package com.kaige123;import java.awt.Rectangle;import java.awt.Robot;im ...

  4. 利用Excel制作一个评级工具

    利用Excel制作一个评级工具 基本目标 思路 输入字符+计算 方法一 方法二 根据计算结果+输出字符 总结 基本目标 做一个简单快速的评级工具. 希望做到评价人在区域(1)中输入单项评价,区域(3) ...

  5. 怎么将多张图片拼在一起?分享几种好用的拼图工具

    怎么把多张图片拼图拼在一起呢?将图片拼在一起并不少见,相信大家在各种社交平台上都会看到别人发的拼图照片.最多就是将出去旅游或者是美食拍下的照片,拼在一起形成一个合照,看上去既展示很多的内容,还不会有紊 ...

  6. 组件是全局怎么修改样式_用一个落地项目,帮你掌握Sketch组件的制作思路

    相信大家对于sketch组件并不陌生,作为sketch官方推出的功能,相对比较久了,不知大家是否还停留在只会建立单个组件,不会组合使用的情况.我最近在项目中也在做这个组件的事情,接下来会以落地项目.实 ...

  7. 制作一个小工具:自动生成“将特定枚举值转换成字符串的C++函数”的代码

    需求 假设我有一种枚举类型: enum fruit_type {apple,banana,orange, }; 我时常会遇到需要将枚举值转换为字符串的情况,即我需要如下的函数: const char* ...

  8. 【UE4+Houdini+Bridge】程序化地形生成和野外植被撒点工具制作思路

    B站制作过程展示: Houdini To UE4 程序化地形生成制作过程与效果展示 Github Houdini与HDA源文件:Houdini-PCG-Environment-Generator 最终 ...

  9. 转载一个手机RPG游戏制作工具,仿造RPGXP写的

    转载一个手机RPG游戏制作工具,仿造RPGXP写的 有朋友问有没有脚本编辑功能,大家注意啦: 有脚本编辑功能,可视化界面编辑脚本,和RMXP一样 经过一年的开发,手机RPG游戏制作工具--MobieG ...

最新文章

  1. sqoop2增量导入无法指定last value问题解决方法
  2. python 进阶:修饰器的介绍
  3. mysql集群安装配置
  4. Oozie JMS通知消息实现--根据作业ID来过滤消息
  5. ASP.NET Core在MacOS上建立HTTPS开发证书
  6. Oracle GoldenGate Director安装和配置(无图)
  7. 利用HTML5开发Android笔记(中篇)
  8. Ubuntu 配置VNC时,出现“perl: warning: Falling back to the standard locale (C).”等提示错误解决方法...
  9. Unity零基础到入门 ☀️| Unity常用知识点介绍,游戏组成+游戏对象+地形+坐标系等等(必备知识)
  10. 判定两个点是否在一条直线的同一侧_高中物理的常用方法、题型特点及应用注意点,不看很吃亏...
  11. 计算机科学导论第五版第二章答案,(计算机科学导论第2章答案.docx
  12. animatext.js文字动画js特效插件
  13. 石化能源行业工业互联网智能工厂解决方案
  14. ERROR: Error in Log_event::read_log_event(): ‘Sanity check failed‘, data_len: 67, event_type: 35
  15. java4android网易云,Android仿网易云音乐播放界面
  16. React之HOC(高阶组件)
  17. ffmpeg用drawtext filter 给视频加字幕,代码实现
  18. 把一个人的特点写具体作文_把一个人的特点写具体的作文
  19. 【十四】MySQL Innodb RR隔离级别下到底是不是解决了幻读
  20. 百度智能云牵手中国跳水队,体育和AI正在酝酿新化学反应

热门文章

  1. 配置JAVA和配置Android -sdk步骤
  2. caffe特征可视化---python实现
  3. j剑指offer面试题[33]-把数组排成最小的数
  4. Java打卡Day4-算术运算符
  5. 性能测试(一)性能测试是什么?有哪些分类?
  6. java switch原则_Java switch case语句
  7. linux 内核 网卡驱动 移植,linux内核移植步骤添加dm9000网卡驱动(设备树).docx
  8. mysql 日期 1970_Mysql中处理1970年前的日期(unixtime为负数的情况)负数时间戳格式化...
  9. build tut framework on ubuntu
  10. qt-opensource-windows-x86-vs2010-4.8.6 + qt-creator-windows-opensource-2.8.0