너무 많은 코드를 작성하지 않고도 C #을 사용하여 SVG 이미지를 PNG로 변환하려고했습니다. 누구든지이를 위해 라이브러리 나 예제 코드를 추천 할 수 있습니까?
너무 많은 코드를 작성하지 않고도 C #을 사용하여 SVG 이미지를 PNG로 변환하려고했습니다. 누구든지이를 위해 라이브러리 나 예제 코드를 추천 할 수 있습니까?
답변:
이를 위해 inkscape의 명령 줄 버전을 호출 할 수 있습니다.
http://harriyott.com/2008/05/converting-svg-images-to-png-in-c.aspx
또한 C # SVG 렌더링 엔진이 있습니다. 주로 SVG 파일이 문제인 경우 필요에 맞는 codeplex의 웹에서 사용할 수 있도록 설계되었습니다.
원본 프로젝트
http://www.codeplex.com/svg
수정 사항 및 추가 활동이 포함 된 포크 : (2013 년 7 월 추가됨)
https://github.com/vvvv/SVG
image
요소가 구현되지 않았습니다 - 나는 소스 코드를 확인했습니다. @FrankHale raphael이 두 번 추가했기 때문에 svg에서 xmlns를 제거해야했습니다.
http://svg.codeplex.com/ (최신 버전 @ GIT , @ NuGet ) 라이브러리를 사용하는 훨씬 쉬운 방법이 있습니다 . 내 코드는 다음과 같습니다.
var byteArray = Encoding.ASCII.GetBytes(svgFileContents);
using (var stream = new MemoryStream(byteArray))
{
var svgDocument = SvgDocument.Open(stream);
var bitmap = svgDocument.Draw();
bitmap.Save(path, ImageFormat.Png);
}
image
요소를 지원하지 않기 때문에 사용해야했습니다 .
object not set to an instance of an object
실행할 때 발생 var bitmap = svgDocument.Draw();
합니다. 뭐가 문제 야?
서버에서 svg를 래스터 화해야했을 때 P / Invoke를 사용하여 librsvg 함수를 호출했습니다 (Windows 버전의 김프 이미지 편집 프로그램에서 dll을 가져올 수 있음).
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string pathname);
[DllImport("libgobject-2.0-0.dll", SetLastError = true)]
static extern void g_type_init();
[DllImport("librsvg-2-2.dll", SetLastError = true)]
static extern IntPtr rsvg_pixbuf_from_file_at_size(string file_name, int width, int height, out IntPtr error);
[DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool gdk_pixbuf_save(IntPtr pixbuf, string filename, string type, out IntPtr error, __arglist);
public static void RasterizeSvg(string inputFileName, string outputFileName)
{
bool callSuccessful = SetDllDirectory("C:\\Program Files\\GIMP-2.0\\bin");
if (!callSuccessful)
{
throw new Exception("Could not set DLL directory");
}
g_type_init();
IntPtr error;
IntPtr result = rsvg_pixbuf_from_file_at_size(inputFileName, -1, -1, out error);
if (error != IntPtr.Zero)
{
throw new Exception(Marshal.ReadInt32(error).ToString());
}
callSuccessful = gdk_pixbuf_save(result, outputFileName, "png", out error, __arglist(null));
if (!callSuccessful)
{
throw new Exception(error.ToInt32().ToString());
}
}
나는 이것을 위해 Batik 을 사용하고 있습니다. 완전한 Delphi 코드 :
procedure ExecNewProcess(ProgramName : String; Wait: Boolean);
var
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
begin
FillChar(StartInfo, SizeOf(TStartupInfo), #0);
FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil, False,
CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS,
nil, nil, StartInfo, ProcInfo);
if CreateOK then begin
//may or may not be needed. Usually wait for child processes
if Wait then
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
end else
ShowMessage('Unable to run ' + ProgramName);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
procedure ConvertSVGtoPNG(aFilename: String);
const
ExecLine = 'c:\windows\system32\java.exe -jar C:\Apps\batik-1.7\batik-rasterizer.jar ';
begin
ExecNewProcess(ExecLine + aFilename, True);
end;
Batik
하고 C # 또는 다른 언어에서 호출 할 수있는 Java 라이브러리임을 명확히 할 수 있습니다 (이 경우에는 Delphi에서 호출하는 방법을 보여주었습니다)
@Anish의 응답에 추가하려면 SVG를 이미지로 내보낼 때 텍스트가 보이지 않는 문제가있는 경우 SVGDocument의 하위 항목을 반복하는 재귀 함수를 만들 수 있습니다. 다음과 같은 경우 SvgText로 캐스트 해보십시오. 가능하고 (자신의 오류 검사 추가) 글꼴 모음과 스타일을 설정합니다.
foreach(var child in svgDocument.Children)
{
SetFont(child);
}
public void SetFont(SvgElement element)
{
foreach(var child in element.Children)
{
SetFont(child); //Call this function again with the child, this will loop
//until the element has no more children
}
try
{
var svgText = (SvgText)parent; //try to cast the element as a SvgText
//if it succeeds you can modify the font
svgText.Font = new Font("Arial", 12.0f);
svgText.FontSize = new SvgUnit(12.0f);
}
catch
{
}
}
질문이 있으면 알려주세요.
이를 위해 altsoft xml2pdf lib를 사용할 수 있습니다.