Я пытаюсь заменить поток изображения в документе SDF, используя PDFNet 7.0.4
и netcoreapp3.1
. В максимально возможной степени я хочу сохранить исходный объект и его метаданные; те же размеры, цветовая система, компрессия и т. д. c. В идеале номер объекта и даже генерация должны оставаться неизменными - цель состоит в том, чтобы сравнение до и после показывало только измененные пиксели в потоке.
Я получаю необработанные данные пикселей в виде объекта Stream
с помощью этого метода:
private Stream GetImageData(int objectNum)
{
var image = new PDF.Image(sdfDoc.GetObj(objectNum));
var bits = image.GetBitsPerComponent();
var channels = image.GetComponentNum();
var bytesPerChannel = bits / 8;
var height = image.GetImageHeight();
var width = image.GetImageWidth();
var data = image.GetImageData();
var len = height * width * channels * bytesPerChannel;
using (var reader = new pdftron.Filters.FilterReader(data))
{
var buffer = new byte[len];
reader.Read(buffer);
return new MemoryStream(buffer);
}
}
После манипулирования данными изображения я хочу обновить его перед сохранением базового SDFDoc
объект. Я попытался использовать следующий метод:
private void SetImageData(int objectNum, Stream stream)
{
var image = new PDF.Image(sdfDoc.GetObj(objectNum));
var bits = image.GetBitsPerComponent();
var channels = image.GetComponentNum();
var bytesPerChannel = bits / 8;
var height = image.GetImageHeight();
var width = image.GetImageWidth();
var len = height * width * channels * bytesPerChannel;
if (stream.Length != len) { throw new DataMisalignedException("Stream length does not match expected image dimensions"); }
using (var ms = new MemoryStream())
using (var writer = new pdftron.Filters.FilterWriter(image.GetImageData()))
{
stream.CopyTo(ms);
writer.WriteBuffer(ms.ToArray());
}
}
Это работает без ошибок, но на самом деле ничего не обновляется. Я пытался поиграть с SDFObj.SetStreamData()
, но так и не смог сделать это. Каков наименьший эффект и самый быстрый способ напрямую заменить только необработанные пиксельные данные в потоке изображения?
edit
У меня есть эта половина работы с этот метод:
private void SetImageData(int objectNum, Stream stream)
{
var sdfObj = sdfDoc.GetObj(objectNum);
var image = new PDF.Image(sdfObj);
var bits = image.GetBitsPerComponent();
var channels = image.GetComponentNum();
var bytesPerChannel = bits / 8;
var height = image.GetImageHeight();
var width = image.GetImageWidth();
var len = height * width * channels * bytesPerChannel;
if (stream.Length != len) { throw new DataMisalignedException("Stream length does not match expected image dimensions"); }
var buffer = new byte[len];
stream.Read(buffer, 0, len);
sdfObj.SetStreamData(buffer);
sdfObj.Erase("Filters");
}
Это работает, как и ожидалось, но с очевидным предостережением, что он просто игнорирует любое существующее сжатие и превращает изображение в необработанный несжатый поток.
Я пробовал sdfObj.SetStreamData(buffer, image.GetImageData());
и sdfObj.SetStreamData(buffer, image.GetImageData().GetAttachedFilter());
, и это обновляет объект в файле, но результирующее изображение не отображается.