大家好呀,我是一名Java开发工程师,最近公司项目遇到PDF转图片超时问题,经过排查,PDF文件大概在2-3M左右,使用pdfbox转换大概7-8秒(并且存在转换空白的问题),使用icepdf更长,经测试多天,最终放弃Java开发方式去做。使用C#做个个小的winform工具发现 速度还蛮快,打算用.NET WEBAPI写个接口进行PDF转图片,我把代码给大家,目前百度上没这么全的,给大家闭坑了。
项目引用包如下:
大家直接在NuGet里面搜索安装即可!下面正式开始:
首先获取PDF文件转图片流:
//此处入参为PDF的base64编码,大家按照自己的需求来选择用哪段 byte[] data = Convert.FromBase64String(pdfToImageDTO.param); Stream stream = new MemoryStream(data); var pdf = PdfDocument.Load(stream); //此处入参为PDF的文件路径,大家按照自己的需求来选择用哪段 //string strpdfPath = txtPDF.Text.ToString(); //var pdf = PdfDocument.Load(strpdfPath); var pdfpage = pdf.PageCount; var pagesizes = pdf.PageSizes; //先转换获取所有图片List List<Image> images = new List<Image>(); for (int i = 1; i <= pdfpage; i++) { Size size = new Size((int)pagesizes[(i - 1)].Width, (int)pagesizes[(i - 1)].Height); //这里的100大家可以调高调低,越高越清晰,相应的转换时间和文件也会变大 Image image = pdf.Render(i - 1, size.Width, size.Height, 100, 100, PdfRenderFlags.CorrectFromDpi); images.Add(image); } //再将图片列表合并并转换成base64(此处调用我封装的工具类,后面会提供代码) return PdfToImageUtil.ImagesMerge(images);
我封装了个工具类PDFTOIMAGEAPI.cs(该工具类主要将图片流拼接成一个图片,并返回Base64编码):
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace PDFTOIMAGEAPI.Utils { public class PdfToImageUtil { /// <summary> /// 图片合并并返回Base64编码 /// </summary> /// <param name="images"></param> /// <returns></returns> public static string ImagesMerge(List<Image> images) { //把合并的图片进行保存为jpg格式 MemoryStream stream = new MemoryStream(); if (images.Count == 0) { return "图片列表为空,无法转换!"; } else if (images.Count > 1) { //最大宽度和高度 int maL = 0, totalH = 0; //循环遍历获取文件的最大宽度与总高度 foreach (Image image in images) { if (image.Width > maL) maL = image.Width; totalH = totalH + image.Height; } if (totalH == 0 || maL == 0) return null; ; using (Bitmap map = new Bitmap(maL, totalH)) //定义画布 { Graphics g = Graphics.FromImage(map);//定义画笔 g.Clear(Color.White);//把画布更改为白色 int y = 0;//y轴坐标 foreach (Image image in images) { g.DrawImage(image, new Point(0, y)); y = y + image.Height;//y的告诉 5是为了让画布有个缝隙 } map.Save(stream, ImageFormat.Jpeg); //如果需要保存成图片文件,可以使用下面这段注释掉的代码 //map.Save("F:\\1.jpg", ImageFormat.Jpeg); } } else { images[0].Save(stream, ImageFormat.Jpeg); } byte[] arr = new byte[stream.Length]; stream.Position = 0; stream.Read(arr, 0, (int)stream.Length); stream.Close(); //这里将arr强转Base64 return Convert.ToBase64String(arr); } } }