delphi Image32 图片转换成SVG
image32中有2种算法转换图像为svg,一种是按透明度计算找边缘,另一种是分析像素梯度找边缘,demo代码整理后如下:
unit uFrmImageToSVG; interface uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus,
Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls, //
Img32, uSvgWriter; type
TfrmImageToSVG = class(TForm)
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Panel1: TPanel;
btnOpen: TSpeedButton;
btnSaveAs: TSpeedButton;
rbRasterImage: TRadioButton;
rbRasterVectors: TRadioButton;
rbSmoothedAndSimplified: TRadioButton;
ckbHighlightVertices: TCheckBox;
pnlSmooth: TPanel;
lblSmooth: TLabel;
lblSimplify: TLabel;
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
PaintBox1: TPaintBox;
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure btnOpenClick(Sender: TObject);
procedure TrackBarChange(Sender: TObject);
procedure RadioOnClick(Sender: TObject);
procedure ckbHighlightVerticesClick(Sender: TObject);
procedure btnSaveAsClick(Sender: TObject);
private
masterImg, workImg: TImage32;
hasTransparency: Boolean; // must be checked before resizing
rawPaths, bezierPaths, smoothedPaths: TPathsD;
function GetDisplaySize: TSize;
procedure DisplayImage;
public
{ Public declarations }
end; var
frmImageToSVG: TfrmImageToSVG; implementation {$R *.dfm}
{$R Image2.res} uses
Winapi.ShellAPI, System.Math, //
Img32.Draw, Img32.Vector, Img32.Extra, Img32.Vectorizer, Img32.Fmt.BMP,
Img32.Fmt.JPG, Img32.Fmt.PNG; const
C_Margin = 20; function Count(const paths: TPathsD): integer;
var
i: integer;
begin // 统计路径中有多少个点
Result := 0;
for i := 0 to High(paths) do
inc(Result, Length(paths[i]));
end; procedure TfrmImageToSVG.btnOpenClick(Sender: TObject);
begin // 打开图像
if not OpenDialog1.Execute then
Exit;
masterImg.LoadFromFile(OpenDialog1.FileName);
hasTransparency := masterImg.hasTransparency; // 打开的图像是否透明.
masterImg.ScaleToFit(1000, 1000); // 图像缩放到指定尺寸
DisplayImage; // 重新计算图像
end; procedure TfrmImageToSVG.btnSaveAsClick(Sender: TObject);
begin // 保存为
SaveDialog1.InitialDir := OpenDialog1.InitialDir;
SaveDialog1.FileName := ChangeFileExt(ExtractFileName(OpenDialog1.FileName), '.svg');
if not SaveDialog1.Execute then
Exit; with TSimpleSvgWriter.Create(frEvenOdd) do // SVG 写对象
try
AddPaths(smoothedPaths, false, $40000033, $FF000033, 1.2); // 后3个参数为 填充颜色,边线颜色,连线宽度
SaveToFile(SaveDialog1.FileName, 800, 600); // 保存 SVG,参数:文件名,最大宽度,最大高度,边缘宽度[不指定(默认20)]
finally
free;
end;
ShellExecute(0, 'open', PChar(SaveDialog1.FileName), nil, nil, SW_SHOW); // 保存完成后,使用默认程序打开 svg
StatusBar1.Panels[1].Text := format(' %s saved.', [ExtractFileName(SaveDialog1.FileName)]);
end; procedure TfrmImageToSVG.ckbHighlightVerticesClick(Sender: TObject);
begin // 高亮显示顶点 变化 ,重新计算绘制
DisplayImage;
end; procedure TfrmImageToSVG.DisplayImage;
var
i, j: integer;
scale, simplifyTol: double;
vectorBounds: TRect;
// tmpColors: TArrayOfColor32;
begin
rawPaths := nil;
bezierPaths := nil;
smoothedPaths := nil; PaintBox1.Invalidate; if masterImg.IsEmpty then
Exit; if rbRasterImage.Checked then //光栅图像
begin
workImg.Assign(masterImg); // shows the raw image only
with GetDisplaySize do
workImg.ScaleToFit(cx - C_Margin * 2, cy - C_Margin * 2);
// // otherwise, show as a monochrome image
// tmpColors := GetColorMask(workImg, clBlack32, CompareRGB, $32);
// Move(tmpColors[0], workImg.Pixels[0], Length(tmpColors) * SizeOf(TColor32));
StatusBar1.Panels[0].Text := '';
StatusBar1.Panels[1].Text := ' Raw raster image';
Exit;
end; with GetDisplaySize do
workImg.SetSize(cx, cy);
if rbRasterVectors.Checked then //光栅矢量
simplifyTol := 0
else //平滑简化
simplifyTol := TrackBar2.Position * 0.5; //简化容差 (TrackBar2.Position 最大值为 10) // 1. Vectorize (now includes vector simplification):converts simple (2 color) raster images into vector images
// 矢量化(现在包括矢量简化):将简单(2色)光栅图像转换为矢量图像
if hasTransparency then
rawPaths := Vectorize(masterImg, $FF000000, CompareAlpha, $80, simplifyTol) //透明度对比 矢量化 $80:颜色容差 simplifyTol:简化容差
else
rawPaths := Vectorize(masterImg, $FF000000, CompareRGB, $44, simplifyTol); //颜色值对比 矢量化 $44:颜色容差 simplifyTol:简化容差 vectorBounds := GetBounds(rawPaths); //获取路径区域
if vectorBounds.IsEmpty then
Exit; // offset and scale the vector image 偏移和缩放矢量图像 rawPaths := TranslatePath(rawPaths, C_Margin - vectorBounds.Left, C_Margin - vectorBounds.Top); //平移图像(留出边缘距离) // 实际大小与显示大小,计算合适的缩放比
scale := Min((workImg.Width - C_Margin * 2) / RectWidth(vectorBounds), (workImg.Height - C_Margin * 2) / RectHeight(vectorBounds));
rawPaths := ScalePath(rawPaths, scale); //缩放路径 if rbRasterVectors.Checked then //光栅矢量
begin
smoothedPaths := rawPaths;
StatusBar1.Panels[0].Text := format(' Vertices: %d', [Count(rawPaths)]);
StatusBar1.Panels[1].Text := ' Raw Vectors (no smoothing or simplification)';
end
else
begin //平滑简化
smoothedPaths := SmoothPaths(rawPaths, true, (10 - TrackBar1.Position) / 10, 0.25); //参数2:路径闭合 参数3:张力(决定平滑度) 参数4:形状公差
lblSmooth.Caption := format('Smooth'#10'Amount'#10'(%d)', [TrackBar1.Position]); //平滑度 TrackBar1最大值为10
lblSimplify.Caption := format('Simplify'#10'Amount'#10'(%d)', [TrackBar2.Position]); //差化容差
StatusBar1.Panels[0].Text := format(' Vertices: %d', [Count(smoothedPaths)]);
StatusBar1.Panels[1].Text := ' Simplified & smoothed';
end; if ckbHighlightVertices.Checked then //高亮显示顶点
begin
DrawPolygon(workImg, smoothedPaths, frEvenOdd, $20660000); //绘制多边开
DrawLine(workImg, smoothedPaths, DPIAware(2), clMaroon32, esPolygon); //绘制多边开连线
for i := 0 to High(smoothedPaths) do
for j := 0 to High(smoothedPaths[i]) do
DrawPoint(workImg, smoothedPaths[i][j], DPIAware(2.5), clNavy32); //绘制多边形顶点
end
else
begin
DrawPolygon(workImg, smoothedPaths, frEvenOdd, $FF660033); //绘制多边开
end; end; procedure TfrmImageToSVG.FormCreate(Sender: TObject);
begin
self.BorderStyle := bsNone;
//
masterImg := TImage32.Create;
masterImg.LoadFromResource('beetle', 'PNG'); // 从资源中加载图片.
hasTransparency := masterImg.hasTransparency; // 是否透明
masterImg.ScaleToFit(1000, 1000); // 调整到指定尺寸
OpenDialog1.InitialDir := ExtractFilePath(paramStr(0)) + 'sample_images'; // 样办图片位置
ForceDirectories(OpenDialog1.InitialDir);
OpenDialog1.FileName := 'book.bmp';
if hasTransparency then
masterImg.CropTransparentPixels; // 裁剪透明像素
workImg := TImage32.Create;
end; procedure TfrmImageToSVG.FormDestroy(Sender: TObject);
begin
masterImg.free;
workImg.free;
end; procedure TfrmImageToSVG.FormResize(Sender: TObject);
begin
if not(csDestroying in ComponentState) then
begin
Invalidate;
DisplayImage; // 重新计算绘制
end;
end; function TfrmImageToSVG.GetDisplaySize: TSize;
begin
Result.cx := PaintBox1.ClientWidth; // ClientWidth - pnlSmooth.Width;
Result.cy := PaintBox1.ClientHeight; // ClientHeight - StatusBar1.Height;
end; procedure TfrmImageToSVG.PaintBox1Paint(Sender: TObject);
begin
workImg.CopyToDc(PaintBox1.Canvas.Handle); // 绘制到 PaintBox
end; procedure TfrmImageToSVG.RadioOnClick(Sender: TObject);
begin // 切换不同的显示模式
pnlSmooth.Visible := Sender = rbSmoothedAndSimplified;
if pnlSmooth.Visible then
TrackBar1.SetFocus;
DisplayImage; // 重新计算绘制
end; procedure TfrmImageToSVG.TrackBarChange(Sender: TObject);
begin // 简化 及 平整 发生变化
DisplayImage; // 重新计算绘制
end; end.
效果如下:

欢迎微信搜一搜 IT软件部落 关注公众号,你可以了解更详细的内容

欢儿微信扫码关注 IT软件部落 公众号,你可以了解更详细的内容

delphi Image32 图片转换成SVG的更多相关文章
- FilterFactory是一款将图片转换成SVG的在线生成工具。
FilterFactory是一款将图片转换成SVG的在线生成工具. FilterFactory 彩蛋爆料直击现场 FilterFactory是一款将图片转换成SVG的在线生成工具.
- delphi将图片转换成Base64编码函数
{************************************************************************** 名称: BaseImage 参数: fn: TF ...
- 使用CSS将图片转换成黑白(灰色、置灰)z转
小tip: 使用CSS将图片转换成黑白(灰色.置灰) by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.c ...
- 小tip: 使用CSS将图片转换成模糊(毛玻璃)效果
去年盛夏之时,曾写过“小tip: 使用CSS将图片转换成黑白”一文,本文的模式以及内容其实走得是类似路线.CSS3 → SVG → IE filter → canvas. 前段时间,iOS7不是瓜未熟 ...
- [转] 小tip: 使用CSS将图片转换成模糊(毛玻璃)效果 ---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=3804 去年盛夏之时, ...
- 小tip: 使用CSS将图片转换成黑白(灰色、置灰)[转]
小tip: 使用CSS将图片转换成黑白(灰色.置灰) 这篇文章发布于 2012年08月19日,星期日,20:41,归类于 css相关, SVG相关. 阅读 159943 次, 今日 146 次 ...
- [转]C#将image中的显示的图片转换成二进制
本文转自:http://www.cnblogs.com/shuang121/archive/2012/07/09/2582654.html .将Image图像文件存入到数据库中 我们知道数据库里的Im ...
- ABBYY如何把图片转换成pdf格式
在制作工作文件的时候,有时候会遇到需要进行文件格式转换的情况,比较常见的文件格式转换就包含了Office与pdf格式之间的转换.但除此之外,图片与pdf格式也是可以进行转换的,那么图片要怎么操作,才能 ...
- C#将image中的显示的图片转换成二进制
原文:C#将image中的显示的图片转换成二进制 1.将Image图像文件存入到数据库中 我们知道数据库里的Image类型的数据是"二进制数据",因此必须将图像文件转换成字节数组才 ...
- 【caffe-windows】 caffe-master 之 训练自己数据集(图片转换成lmdb or leveldb)
前期准备: 文件夹train:此文件夹中按类别分好子文件夹,各子文件夹里存放相应图片 文件夹test:同train,有多少类就有多少个子文件夹 trainlabels.txt : 存的是训练集的标签 ...
随机推荐
- CentOS 7.3离线安装 JDK
1.下载对应的JDK版本 # 网盘链接:https://pan.baidu.com/s/1HMCJis-FEicIcDTgbksBnQ # 密码:q65m 2.查看原系统jdk版本 [bw@local ...
- PyJWT 和 python-jose 在处理JWT令牌处理的时候的差异和具体使用
PyJWT 和 python-jose 是两个用于处理 JSON Web Tokens (JWT) 的 Python 库.它们都有助于生成.解码.验证和管理 JWT,但它们在功能范围和设计哲学上有一些 ...
- 【漏洞分析】Penpie 攻击事件:重入攻击构造奖励金额
背景信息 2024 年 9月 3日,Penpie 合约遭受重入攻击,攻击者在重入阶段向合约添加流动性来冒充奖励金额,从而获取合约内原有的奖励代币.资产损失高达 2734 万美元. 2024 年 5月, ...
- 《linux实用指令积累》持续更新。。。
一.远程服务器文件拷贝 1.1.scp scp /home/a.txt root@127.0.0.1:/home/ 1.2.sshpass(适用于脚本调用,直接指定密码) 1.2.1.安装sshpas ...
- kubernetes删除ns异常状态为:Terminating
在部署kuboard控制平台的时候,不规范删除,导致ns状态为Terminating [root@master01 ~]# kubectl delete namespace kuboard ^C ro ...
- [OI] Kruskal 重构树
算法介绍 Kruskal 重构树用于快速判断节点的连通性. 考虑到,假如两个节点是联通的,则他们之间总会有一条边被选入最小生成树内,因此他们在最小生成树内也是联通的. 也就是说,我们可以通过求最小生成 ...
- 【漏洞分析】20240507-SATURN:当闪电贷遇上有缺陷的通缩机制
背景信息 2024 年 5 月 6 日,SATURN 代币遭受价格操控攻击,损失 15 BNB.攻击发生的原因是由于 SATURN 代币的代币通缩机制设计不合理,使得攻击者可以通过燃烧池子中的 SAT ...
- 深入探索Spring AI:源码分析流式回答
在上一章节中,我们深入分析了Spring AI的阻塞式请求与响应机制,并探讨了如何增强其记忆能力.今天,我们将重点讲解流式响应的概念与实现.毕竟,AI的流式回答功能与其交互体验密切相关,是提升用户满意 ...
- DOM 的事件流
事件流分为三个阶段:捕获 ==>目标 ==>冒泡 1. 事件捕获阶段:事件传播由目标节点的祖先节点逐级传播到目标节点.先由文档的根 节点 document(window)开始触发对象,最后 ...
- Vue中如何自定义过滤器 ?
过滤器可以格式化我们所需要的数据格式 : 自定义过滤器分为全局和局部过滤器: 全局过滤器在 main.js 中使用 Vue.direct4ive( 过滤器名字,定义过滤器的具体行为函数 ) : 局部 ...