为什么扫描的 pdf 页面以顺时针旋转 90 度返回 - 将其提取为图像时?
Why is a scanned pfd page returned in 90 clockwise rotation - when extracting it as an image?
我使用 iText 7 将 pdf 页面转换为图像(来自扫描文档),以便我可以使用 ocr 处理它。对于某些 pdf 文件,这非常有效,但对于其他文件,图像 "extracted" 会以 90 度旋转返回!
考虑到工作正常的文档:
我打开word,输入一些文字和图片,然后将文件转换为pdf。当对此类文件使用 iText 7 时,我可以毫无问题地获取文本和图像!
考虑导致问题的文档:
我扫描一封信,然后将一个 pdf 文件 X 发送到我的电子邮件中。 X只有一个图像层。如果我用 iText 7 解析 X 并从我得到的字节数组创建一个新图像(使用事件类型 Render_IMAGE 的 EventListener),图像是用 90 度旋转创建的???
因此,对于两个文档,我使用相同的 C# 代码,但输出不同...
我使用了 X(带旋转的)的输出图像并将其转换为 pdf 文件。让我们称之为 Y。所以当我再次从 Y 创建图像时,新图像与 Y 相比没有旋转! - 我只是做这个测试,看看图像是否总是旋转......
//IEventListener 的实现:
public void EventOccurred(IEventData data, EventType type)
{
switch (type)
{
case EventType.RENDER_IMAGE:
String filename;
ImageRenderInfo renderInfo = (ImageRenderInfo)data;
PdfImageXObject image = renderInfo.GetImage();
if (image == null)
{
return;
}
byte[] imageBytes = image.GetImageBytes(true);
extension = image.IdentifyImageFileExtension();
filename = String.Format(@"{0}\{1}.{2}", path, Guid.NewGuid().ToString(), extension);
images.Add(new ImageStreamObject(imageBytes, filename));
break;
}
}
//ClassImageStreamObject
public class ImageStreamObject
{
byte[] image;
string path;
/// <summary>
/// Creates a data object for storing an image as a byte array and its filepath.
/// </summary>
/// <param name="byteArray"></param>
/// <param name="filePath"></param>
public ImageStreamObject(byte[] byteArray, string filePath)
{
image = byteArray;
path = filePath;
}
public String GetImagePath()
{
return path;
}
//做图像的对象的构造函数"extraction":
public PdfImageExtractor(string filePath, string imageOutputPath)
{
pdf = new PdfDocument(new PdfReader(filePath));
listener = new ImageRenderListener(imageOutputPath);
parser = new PdfCanvasProcessor(listener);
imageBuffer = new List<string>();
}
//PdfImageExtractor 创建图像文件的方法:
public List<string> CreateImagesFromPdfPage(int page)
{
FileStream fs;
byte[] tempImage;
string tempPath;
listener.GetImageStreamObjects().Clear();
parser.ProcessPageContent(pdf.GetPage(page));
imageStreamObjects = listener.GetImageStreamObjects();
List<string> pathes = GetImagePathes();
imageStreamObjects.ForEach(delegate (ImageStreamObject imageStreamObject)
{
tempPath = imageStreamObject.GetImagePath();
tempImage = imageStreamObject.GetImageAsByteArray();
fs = new FileStream(tempPath, FileMode.Create);
fs.Write(tempImage, 0, tempImage.Length);
fs.Flush();
fs.Close();
});
return pathes;
}
您提取的位图图像与作为资源存储在 PDF 中的完全一样(至少在方向上是这样)。但是每当绘制位图资源时,它都受制于绘制时的当前变换矩阵,并且当前变换可以显着旋转、倾斜、平移和拉伸位图。
您可以使用
从ImageRenderInfo renderInfo
绘制位图时检索当前变换矩阵的值
Matrix ctm = renderInfo.GetImageCtm();
分析一下。此外,您必须考虑页面旋转,您可以从页码 page
中检索到
int rotation = pdf.GetPage(page).GetRotation()
我使用 iText 7 将 pdf 页面转换为图像(来自扫描文档),以便我可以使用 ocr 处理它。对于某些 pdf 文件,这非常有效,但对于其他文件,图像 "extracted" 会以 90 度旋转返回!
考虑到工作正常的文档: 我打开word,输入一些文字和图片,然后将文件转换为pdf。当对此类文件使用 iText 7 时,我可以毫无问题地获取文本和图像!
考虑导致问题的文档: 我扫描一封信,然后将一个 pdf 文件 X 发送到我的电子邮件中。 X只有一个图像层。如果我用 iText 7 解析 X 并从我得到的字节数组创建一个新图像(使用事件类型 Render_IMAGE 的 EventListener),图像是用 90 度旋转创建的???
因此,对于两个文档,我使用相同的 C# 代码,但输出不同...
我使用了 X(带旋转的)的输出图像并将其转换为 pdf 文件。让我们称之为 Y。所以当我再次从 Y 创建图像时,新图像与 Y 相比没有旋转! - 我只是做这个测试,看看图像是否总是旋转......
//IEventListener 的实现:
public void EventOccurred(IEventData data, EventType type)
{
switch (type)
{
case EventType.RENDER_IMAGE:
String filename;
ImageRenderInfo renderInfo = (ImageRenderInfo)data;
PdfImageXObject image = renderInfo.GetImage();
if (image == null)
{
return;
}
byte[] imageBytes = image.GetImageBytes(true);
extension = image.IdentifyImageFileExtension();
filename = String.Format(@"{0}\{1}.{2}", path, Guid.NewGuid().ToString(), extension);
images.Add(new ImageStreamObject(imageBytes, filename));
break;
}
}
//ClassImageStreamObject
public class ImageStreamObject
{
byte[] image;
string path;
/// <summary>
/// Creates a data object for storing an image as a byte array and its filepath.
/// </summary>
/// <param name="byteArray"></param>
/// <param name="filePath"></param>
public ImageStreamObject(byte[] byteArray, string filePath)
{
image = byteArray;
path = filePath;
}
public String GetImagePath()
{
return path;
}
//做图像的对象的构造函数"extraction":
public PdfImageExtractor(string filePath, string imageOutputPath)
{
pdf = new PdfDocument(new PdfReader(filePath));
listener = new ImageRenderListener(imageOutputPath);
parser = new PdfCanvasProcessor(listener);
imageBuffer = new List<string>();
}
//PdfImageExtractor 创建图像文件的方法:
public List<string> CreateImagesFromPdfPage(int page)
{
FileStream fs;
byte[] tempImage;
string tempPath;
listener.GetImageStreamObjects().Clear();
parser.ProcessPageContent(pdf.GetPage(page));
imageStreamObjects = listener.GetImageStreamObjects();
List<string> pathes = GetImagePathes();
imageStreamObjects.ForEach(delegate (ImageStreamObject imageStreamObject)
{
tempPath = imageStreamObject.GetImagePath();
tempImage = imageStreamObject.GetImageAsByteArray();
fs = new FileStream(tempPath, FileMode.Create);
fs.Write(tempImage, 0, tempImage.Length);
fs.Flush();
fs.Close();
});
return pathes;
}
您提取的位图图像与作为资源存储在 PDF 中的完全一样(至少在方向上是这样)。但是每当绘制位图资源时,它都受制于绘制时的当前变换矩阵,并且当前变换可以显着旋转、倾斜、平移和拉伸位图。
您可以使用
从ImageRenderInfo renderInfo
绘制位图时检索当前变换矩阵的值
Matrix ctm = renderInfo.GetImageCtm();
分析一下。此外,您必须考虑页面旋转,您可以从页码 page
中检索到
int rotation = pdf.GetPage(page).GetRotation()