C# .NET "Параметр недействителен", когда изображение в выражении using
Windows 8.1 Pro, Visual Studio 2015, обновление 3, C#, .NET Framework 4.5. Ghostscript.NET (последняя версия), GhostScript 9.20.
Я конвертирую PDF в PDF. Хах. Ну, я делаю "редактируемый" PDF "жесткий" PDF, который не может быть отредактирован и имеет более низкое качество. В процессе я беру редактируемый PDF, сохраняю его в виде x-страниц файлов PNG, преобразую эти файлы PNG в многостраничный TIFF, а затем преобразую многостраничный TIFF в нужный мне PDF-файл.
Это прекрасно работало с Visual Studio 2012, одной из предыдущих версий GhostScript .NET и GS 9.10.
public static Tuple<string, List<string>> CreatePNGFromPDF(string inputFile, string outputfile)
{
Tuple<string, List<string>> t = null;
List<string> fileList = new List<string>();
string message = "Success";
string outputFileName = string.Empty;
int desired_x_dpi = 96;
int desired_y_dpi = 96;
try
{
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(inputFile);
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
{
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))
{
outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
img.Save(outputFileName, ImageFormat.Png);
if (!fileList.Contains(outputFileName))
{
fileList.Add(outputFileName);
}
}
}
}
}
}
catch (Exception ex)
{
message = ex.Message;
}
t = new Tuple<string, List<string>>(message, fileList);
return t;
}
Это теперь терпит неудачу в этой строке:
using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))
при обработке второй страницы. Первая страница работает нормально.
Я скачал исходный код GhostScript.NET, добавил его в свое решение, отладил и т. Д. И потратил немало времени, пытаясь выяснить это.
Затем я решил разделить функциональность и сделать минимум доступным для дальнейшего изучения в простом консольном приложении:
static void Main(string[] args)
{
int xDpi = 96;
int yDpi = 96;
string pdfFile = @"Inputfilenamehere.pdf";
GhostscriptVersionInfo gsVersionInfo = GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | GhostscriptLicense.AFPL, GhostscriptLicense.GPL);
List<GhostscriptVersionInfo> gsVersionInfoList = GhostscriptVersionInfo.GetInstalledVersions(GhostscriptLicense.GPL | GhostscriptLicense.AFPL);
try
{
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(pdfFile);
using (GhostscriptRasterizer gsRasterizer = new GhostscriptRasterizer(gsViewer))
{
int pageCount = gsRasterizer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Image img = gsRasterizer.GetPage(xDpi, yDpi, i + 1);
}
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
И вот, нет проблем. Разница в том, что я не помещаю декларацию своего имиджа в using
заявление.
Я всегда стараюсь быть хорошим разработчиком и использую оператор using всякий раз, когда класс реализует IDisposable
,
Итак, я удалил использование использования и получил PDF-файлы более низкого качества, которые я всегда желал. Моя жизнь сейчас хорошая.
using (GhostscriptViewer gsViewer = new GhostscriptViewer())
{
gsViewer.Open(inputFile);
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
{
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber);
outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
img.Save(outputFileName, ImageFormat.Png);
if (!fileList.Contains(outputFileName))
{
fileList.Add(outputFileName);
}
}
}
}
Обратите внимание, что если я позвоню img.Dispose()
в конце for
цикл, я снова получаю ту же ошибку!
Я думаю, что моя проблема не связана с GhostScript или GhostScript .NET. Я тупица за то, что настаиваю на слепом использовании выражений "using", если класс реализует IDisposable
? Я всегда понимал, что лучше всего оборачивать все, что реализует IDisposable
с using
заявление об отказе от утечек и т. д.
Отсюда мой вопрос: любые идеи, почему я получаю исключение "Параметр неверен" при инициализации System.Drawing.Image
класс в пределах using
заявление, но не тогда, когда я не? Я хотел бы понять это больше.
Еще лучше, если кто-нибудь знает, как я могу получить эту функциональность, а также убедиться, что я правильно избавляюсь от своего объекта, это было бы лучше.
Я не нашел много об этой конкретной теме, когда я искал информацию. Я нашел еще одну публикацию Stackru о том, что кто-то использует графический объект в операторе using с той же ошибкой. Интересно, есть ли отношения? Я также отмечаю, что я должен использовать Dispose (), но это, кажется, вызывает проблему, и мне нужно, чтобы это работало.
К вашему сведению, для тех, кто заинтересован, фактическая ошибка происходит здесь, в GhostscriptInterprester.cs в коде GhostScript .NET:
Метод: public void Run(string str)
str is "Page pdfshowpage_init pdfshowpage_finish"
// GSAPI: run the string
int rc_run = _gs.gsapi_run_string(_gs_instance, str, 0, out exit_code);
1 ответ
Я нашел основную причину моей неудачи, по крайней мере. Мой объект GhostscriptRasterizer имел значение '0', установленное для точек высоты и ширины.
var rasterizer = new GhostscriptRasterizer();
rasterizer.CustomSwitches.Add("-dDEVICEWIDTHPOINTS=" + widthPoints);
rasterizer.CustomSwitches.Add("-dDEVICEHEIGHTPOINTS=" + heightPoints);
Как только я установил для высоты и ширины правильное ненулевое значение, проблема была исправлена.