Reputation: 395
I am trying several ways to remove System.Drawing due to the pending removal of the workaround in .NET 7. I am trying to use SkiaSharp to replace those calls but am having trouble.
The following is what I currently have, which processes Tiff data from a stream and passes it to PdfSharp to construct the final Pdf:
System.Drawing.Image MyImage = System.Drawing.Image.FromStream(inStream);
PdfDocument doc = new PdfDocument();
for (int PageIndex = 0; PageIndex < MyImage.GetFrameCount(FrameDimension.Page); PageIndex++)
{
MyImage.SelectActiveFrame(FrameDimension.Page, PageIndex);
XImage img = XImage.FromGdiPlusImage(MyImage);
var page = new PdfPage();
doc.Pages.Add(page);
XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[PageIndex]);
xgr.DrawImage(img, 0, 0);
}
doc.Save(outStream);
MyImage.Dispose();
I am not sure what the SkiaSharp equivalents would be and have tried searching for them in the docs.
If you have any questions, concerns, or comments, please let me know. Thanks!
Upvotes: 1
Views: 2273
Reputation: 3270
SkiaSharp has no TIFF support, some resources recommend to add TIFF support using LibTiff.net. That works.
public static async Task Main(string[] args)
{
GlobalFontSettings.FontResolver = new FontResolver();
var document = new PdfDocument();
var tempImageFiles = TiffToBitmap(args[0]);
try
{
for (int pageIndex = 0; pageIndex < tempImageFiles.Count; pageIndex++)
{
var pageWithImage = new PdfPage();
document.Pages.Add(pageWithImage);
var xgr = XGraphics.FromPdfPage(document.Pages[pageIndex]);
var xImage = XImage.FromStream(() => File.OpenRead(tempImageFiles[pageIndex]));
xgr.DrawImage(xImage, 0, 0);
}
document.Save("helloworld.pdf");
}
finally
{
foreach (var tempImageFile in tempImageFiles)
{
File.Delete(tempImageFile);
}
}
}
private static List<string> TiffToBitmap(string tiffFilePath)
{
var tempPaths = new List<string>();
using var tiff = Tiff.Open(tiffFilePath, "r");
var numberIfTiffPages = GetNumberofTiffPages(tiff);
for (short i = 0; i < numberIfTiffPages; i++)
{
tiff.SetDirectory(i);
var width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
var height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
var bitmap = new SKBitmap();
var info = new SKImageInfo(width, height);
var raster = new int[width * height];
var ptr = GCHandle.Alloc(raster, GCHandleType.Pinned);
bitmap.InstallPixels(info, ptr.AddrOfPinnedObject(), info.RowBytes, (addr, ctx) => ptr.Free(), null);
if (!tiff.ReadRGBAImageOriented(width, height, raster, Orientation.TOPLEFT))
{
// not a valid TIF image.
return null;
}
if (SKImageInfo.PlatformColorType == SKColorType.Bgra8888)
{
SKSwizzle.SwapRedBlue(ptr.AddrOfPinnedObject(), raster.Length);
}
var encodedData = bitmap.Encode(SKEncodedImageFormat.Png, 100);
var tempPath = Path.Combine(Path.GetTempFileName() + ".png");
using var bitmapImageStream = File.Open(tempPath, FileMode.Create, FileAccess.Write, FileShare.None);
encodedData.SaveTo(bitmapImageStream);
tempPaths.Add(tempPath);
}
return tempPaths;
}
public static int GetNumberofTiffPages(Tiff image)
{
int pageCount = 0;
do
{
++pageCount;
} while (image.ReadDirectory());
return pageCount;
}
I found some hickups (e.g. using SKEncodedImageFormat.Bmp will break the POC... additionaly I want to point to a solution that is a bit less bumpy using ImageSharp.
Upvotes: 1