首页 > 其他分享 >delphi Image32 图片转换成SVG

delphi Image32 图片转换成SVG

时间:2024-06-13 23:23:06浏览次数:14  
标签:begin workImg end Sender SVG delphi TObject Image32 procedure

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.

效果如下:

 

标签:begin,workImg,end,Sender,SVG,delphi,TObject,Image32,procedure
From: https://www.cnblogs.com/bluejade/p/18246947

相关文章

  • delphi Image32 SVG图形查看器
    DELPHI 中没有SVG显示组件,需要用到第三方组件,高版本可以使用skia(但必须带上skia.dll).最新版Image32修改了很多,SVGIconImageList 也因此换成了Image32做为基础库,安装了 SVGIconImageList 就可以不用再单独安装Image32了(基本上是绿色不用安装包,直接引用就行)。unituFrmSVGSh......
  • delphi Image32 图形处理 图层
    图形图层处理是Image32的主要功能,矢量图形,分层类似Photoshop看人图层,直接上代码效果。unituFrmLayer;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Types,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,V......
  • delphi Image32 路径
    用Image32的理由之一,也是路径这块做得比delphi(FMX)自带的要好,skia中支持svg,但对路径处理功能不够强大。VCL只能使用第三方库。VCL如果要支持SVG,只有Image32好点,SVGIconImageList 第三方库也使用Image32.  unituFrmPaths;interfaceusesWinapi.Windows,Winapi.M......
  • 窥探 Delphi 的 dcp文件
    之前我猜测Delphi里的dcp类似java里的maven的pom.xml,经过测试发现,和猜想的才不多,既包含了pom.xml的信息,又包含了本bpl的信息;测试如下:在本文中,我将展示如何从Delphi的DCP文件中读取一些非常基本的信息。这包括要链接的BPL名称、所需的DCP和包含的单元。在过去的......
  • Image32 动画演示2
    Image32自带的Demo,添加一些注解。unituFrmAnimation2;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls,Vcl.ExtCtrls,System.Math,Img3......
  • TSkSvg组件使用
    1.把svg静态字符串写死程序里unitUnit1;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,System.Skia,Vcl.Skia,Vcl.StdCtrls;typeTForm1=class(T......
  • 导出 LaTeX 为 SVG
    LaTeX本身并不直接支持导出SVG格式的文档或图片,但可以通过一些工具和插件实现将LaTeX文档或图形转换为SVG格式。使用dvisvgm我们可以先将LaTeX文档编译为DVI格式,再通过dvisvgm工具将DVI文件转换为SVG格式。这个工具是TeXLive发行版的一部分。编译为DVI......
  • Spire.PDF for Java 10.6.0 支持 PDF to SVG, Word and OFD
    Spire.PDFforJava10.6.0enhancestheconversionsfromPDFtoSVG,WordandOFDSpire.DocforJavaisaprofessionalWordAPIthatempowersJavaapplicationstocreate,convert,manipulateandprintWorddocumentswithoutdependencyonMicrosoftWord.B......
  • delphi property中default的含义
    delphiproperty中default的含义首先看个案例TPerson=classpublishedpropertyAge:IntegerreadFAgewriteSetAgedefault20;end;我们创建一个TPerson类给其一个属性,然后使用了default20关键字,按照我们的理解应该是这个age属性的默认值就是20;其实这个d......
  • 界面控件Telerik UI for WPF中文教程 - 用RadSvgImage升级应用程序UI
    TelerikUIforWPF拥有超过100个控件来创建美观、高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序。UIforWPF支持MVVM、触摸等,创建的应用程序可靠且结构良好,非常容易维护,其直观的API将无缝地集成VisualStudio工具箱中。TelerikUIforWPF中的RadSvgImage组件使......