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 : 存的是训练集的标签 ...
随机推荐
- 短视频SDK 视频编辑SDK AE模版SDK 人体抠图SDK 绿幕抠图SDK
优势: 快速接入免费试用名称: 短视频SDK品牌: 蓝松SDK特色: 一站式视音频解决方案 杭州蓝松科技有限公司,多年来一直专注于音视频领域核心技术的研发.核心研发团队掌握的行业领先技术,目前 ...
- armbian指令大全
修复缺失内容 使用以下命令修复安装时缺失的内容: sudo apt --fix-broken install 使用 aptitude 安装软件 aptitude 是 Debian 及其衍生系统中功能强 ...
- 甲方扔给两个存在包名与类名均相同的Jar包,要在工程中同时使用怎么办?
你的项目是否曾遇到过有jar包冲突,而这些冲突的jar包又必须同时存在的情况?一般来说,jar 冲突都是因不同的上层依赖项,自身又依赖了相同 jar 包的不同版本所致,解决办法也都是去除其中一个即可. ...
- 【CentOS7】之执行yum命令报错
备份文件: # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the ...
- docker 命令 报错device or resource busy
背景: docker-compose up -d 运行容器报错:failed to remove root filesystem for xxx: remove /var/lib/docker/dev ...
- Google sheet
最近做比较多 data migration 的东西. 当我们开发一个新的系统去替代一个旧系统时,通常就需要做大量的 migration 动作. 有好几个做法 我之前比较常用的的工具是 sql 和 c# ...
- 痞子衡嵌入式:为下一代AI边缘处理设备而生 - i.MXRT700
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的新品i.MXRT700. 四年前恩智浦官宣了面向下一代智能穿戴设备的 i.MXRT500 系列,这 ...
- Java如何将Object转换成指定Class对象
在Java中,将Object转换为指定类型的Class对象实际上是两个不同概念的操作: 将Object实例转换为特定类型的实例:这通常涉及到类型转换(如(MyType) myObject)或者通过反射 ...
- 【ARMv8】异常级别的定义EL0、EL1、EL2、EL3
Exception levels ARMv8-A系列定义了一系列的异常等级,从EL0到EL3,下面具体说明其含义: ELn中,随着n的增加,软件的执行权限也相应的增加: EL0被称为无特权执行: EL ...
- Java日期时间API系列20-----Jdk8中java.time包中的新的日期时间API类,ZoneId时区ID大全等。
Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格 ...