В случае, если кто-то хочет использовать Ghostscript.NET .
Ghostscript.NET - (записанный в C#) является наиболее завершенной библиотекой управляемой оболочки вокруг библиотеки Ghostscript (32-разрядный & 64-разрядный), интерпретатор для языка PostScript, PDF.
Это зависит от исполняемого файла, который необходимо установить на машине. Вот ссылка от того, где Вы видите и загружаете последнюю версию exe.
P.S. Я испытал некоторые затруднения из-за последней версии 9.50, не бывшей способной считать страницы.
я предпочитаю использовать 9,26 версий.
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw32.exe
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw64.exe
Следующий шаг к [1 120], находят и устанавливают Ghostscript.NET от Nuget. Я загружаю PDF с URL CDN и использую MemoryStream, чтобы открыть и обработать файл PDF. Вот пример кода:
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
using (var ms = new MemoryStream(buffer))
{
rasterizer.Open(ms);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
можно также использовать его с временным FileStream. Вот другой пример. Обратите внимание, что Файл является временным и сделал, чтобы DeleteOnClose отметил.
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
int bufferSize = 4096;
using (var fileStream = System.IO.File.Create("TempPDFolder/" + pdfName, bufferSize, System.IO.FileOptions.DeleteOnClose))
{
// now use that fileStream to save the pdf stream
fileStream.Write(buffer, 0, buffer.Length);
rasterizer.Open(fileStream);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
Hope это поможет кому-то изо всех сил пытающемуся получить высококачественные изображения от PDF бесплатно.
Да, вы делаете это безопасный с точки зрения гонки доступ к полю m_LayoutSuspended
, однако блокировка требуется по следующей причине, если код выполняет следующие действия:
if (!o.IsLayoutSuspended) // This is not thread Safe .....
{
o.SuspendLayout(); // This is not thread Safe, because there's a difference between the checck and the actual write of the variable a race might occur.
...
o.ResumeLayout();
}
Более безопасный способ, использующий CompareExchange
], чтобы убедиться, что не было условий гонки:
private long m_LayoutSuspended = 0;
public bool SuspendLayout()
{
return Interlocked.CompareExchange(ref m_LayoutSuspended, 1) == 0;
}
if (o.SuspendLayout())
{
....
o.ResumeLayout();
}
Или, еще лучше, просто используйте блокировку.
Лично я бы использовал volatile Boolean:
private volatile bool m_LayoutSuspended = false;
public void SuspendLayout()
{
m_LayoutSuspended = true;
}
public void ResumeLayout()
{
m_LayoutSuspended = false;
}
public bool IsLayoutSuspended
{
get { return m_LayoutSuspended; }
}
Опять же, как я недавно признал в другом месте, volatile не означает совсем то, что я думал. Я подозреваю, что это нормально :)
Даже если вы придерживаетесь Interlocked
, я бы изменил его на int
... потенциально нет необходимости создавать 32-битные системы изо всех сил пытаются сделать 64-битную запись атомарной, когда они могут легко сделать это с 32-битной ...