使用场景:再导出PDF中的图片时,通常会用到ImageObject.CloneBitmap()的接口。如果出现导出的图片发生了旋转,翻转等情况,可能是因为该图片对象imageObject的变换矩阵Matrix中有旋转、翻转上的处理,导致PDF显示效果,和实际导出的图片不太一致。
变换矩阵matrix介绍:
Matrix2D={a,b,c,d,e,f}是一个包含6个元素的数组,用来控制对象的缩放、平移、旋转、扭曲。 在PDF中,图形、图片、文本、渐变等几何对象,如果要做几何变换都会用到matrix。
以下是PDF标准中对如何计算matrix的描述:
数组[a,b,c,d,e,f]以矩阵的方式呈现,并用于计算的旋转和拉伸的计算方式1.变换计算的过程(将默认的matrix,进行旋转、缩放、翻转):
缩放变换:Sx和Sy分别表示横纵缩放比例,如果是负的,则会翻转(Sx<0水平翻转,Sy<0垂直翻转)。
旋转变换:Rc=Cosθ ,Rs=Sinθ θ表示逆时针旋转角度
注意:先旋转后翻转 和先翻转后旋转的结果是不同的,顺序不可以变。
计算旋转和翻转情况的代码(C#)示例如下:
using System;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using ErrorCode = foxit.common.ErrorCode;
using foxit.pdf.graphics;
using Bitmap = foxit.common.Bitmap;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Web;
using Image = foxit.common.Image;
using System.IO;
namespace pdf2imageCS
{
class pdf2image
{
public static void Page2Bitmap(PDFPage page,int dpi_x, int dpi_y,String savePath)
{
{
page.StartParse(0, null, true);
//规范化页面,取消页面旋转和pageBox带来的影响
page.Normalize();
page.StartParse(0, null, true);
RectF rectf=new RectF(0,0, page.GetWidth(), page.GetHeight());
float pro_x =(float) dpi_x / 72;
float pro_y = (float)dpi_y / 72;
Matrix2D matrix = page.GetDisplayMatrix(-1 * (int)(rectf.left), -(int)(page.GetHeight() - rectf.top), (int)(page.GetWidth() * pro_x), (int)(page.GetHeight() * pro_y), Rotation.e_Rotation0);//page.GetDisplayMatrix(0,0, width, height, page.GetRotation());
rectf.left = rectf.left * pro_x;
rectf.right = (rectf.right * pro_x);
rectf.bottom = (rectf.bottom * pro_y);
rectf.top = rectf.top * pro_y;
using (Bitmap bitmap = new Bitmap((int)rectf.Width(), (int)rectf.Height(), Bitmap.DIBFormat.e_DIBArgb, IntPtr.Zero, 0))
{
using (Renderer render = new Renderer(bitmap, false))
{
//开始渲染
render.StartRender(page, matrix, null);
{
using (Image image = new Image())
{
image.AddFrame(bitmap);
image.SetDPIs(dpi_x, dpi_y);
//保存图片
image.SaveAs(savePath+" test_" + page.GetIndex() + ".jpg");
}
}
}
}
rectf.Dispose();
matrix.Dispose();
}
}
static void Main(string[] args)
{
ErrorCode error_code = Library.Initialize(sn, key);
if (error_code != ErrorCode.e_ErrSuccess)
{
Console.WriteLine("Library Initialize Error: {0}\n", error_code);
return;
}
String savePath = @"D:\DownLoad\output\";
//转成指定分辨率的图片
using (PDFDoc doc = new PDFDoc(@"D:\DownLoad\output\AboutFoxit.pdf"))
{
doc.Load(null);
for (int i = 0; i < doc.GetPageCount(); i++)
{
using (PDFPage page = new PDFPage(doc.GetPage(i)))
{
Page2Bitmap(page, 72, 72, savePath);
}
}
}
//图片插入PDF,页面大小适应图片尺寸
using (Image image = new Image(savePath + "test_1.jpg"))
using (PDFDoc doc = new PDFDoc())
{
int w = image.GetWidth(), h = image.GetHeight();
using (PDFPage page = doc.InsertPage(0, w, h))
{
page.AddImage(image, 0, new foxit.common.fxcrt.PointF(0, 0), w, h, true);
}
}
//PDF导出txt
using (var doc = new PDFDoc(@"D:\DownLoad\output\AboutFoxit.pdf"))
{
doc.Load(null);
using (var writer = new StreamWriter(savePath + "pdf2text.txt", false, System.Text.Encoding.Unicode))
{
int pageCount = doc.GetPageCount();
for (int i = 0; i < pageCount; i++)
{
using (var page = doc.GetPage(i))
{
page.StartParse((int)PDFPage.ParseFlags.e_ParsePageNormal, null, false);
using (var text_select = new TextPage(page, (int)TextPage.TextParseFlags.e_ParseTextUseStreamOrder))
{
String chars = text_select.GetText(TextPage.TextOrderFlag.e_TextDisplayOrder);
writer.Write(chars);
}
}
}
writer.Close();
}
}
Library.Release();
}
}
}