我有4千万个TIFF文档,都是1位单页双工。在大约40%的情况下,这些TIFF的背面图像是“空白”,我想在加载到CMS之前删除它们以减少空间需求。
有没有一种简单的方法可以查看每个页面的数据内容,如果它低于预设的阈值就删除它,比如2%'黑色'?
我在这方面与技术无关,但C#解决方案可能是最容易支持的。问题是,我没有图像处理经验所以不知道从哪里开始。
编辑添加:图片是旧扫描,所以“脏”,所以预计这不是一门精确的科学。需要设置阈值以避免误报的可能性。
答案 0 :(得分:3)
你可能应该:
Bitmap.GetFrameCount
/ Bitmap.SelectActiveFrame
方法)Bitmap.LockBits
方法)Bitmap.LockBits
和循环)此任务并不是特别复杂,但需要编写一些代码。此站点包含一些您可以使用方法名称作为关键字搜索的样本。
P.S。我假设所有图像都可以成功加载到System.Drawing.Bitmap
。
答案 1 :(得分:1)
您可以使用DotImage执行类似的操作(免责声明,我为Atalasoft工作并编写了您将使用的大多数基础类)。执行此操作的代码如下所示:
public void RemoveBlankPages(Stream source stm)
{
List<int> blanks = new List<int>();
if (GetBlankPages(stm, blanks)) {
// all pages blank - delete file? Skip? Your choice.
}
else {
// memory stream is convenient - maybe a temp file instead?
using (MemoryStream ostm = new MemoryStream()) {
// pulls out all the blanks and writes to the temp stream
stm.Seek(0, SeekOrigin.Begin);
RemoveBlanks(blanks, stm, ostm);
CopyStream(ostm, stm); // copies first stm to second, truncating at end
}
}
}
private bool GetBlankPages(Stream stm, List<int> blanks)
{
TiffDecoder decoder = new TiffDecoder();
ImageInfo info = decoder.GetImageInfo(stm);
for (int i=0; i < info.FrameCount; i++) {
try {
stm.Seek(0, SeekOrigin.Begin);
using (AtalaImage image = decoder.Read(stm, i, null)) {
if (IsBlankPage(image)) blanks.Add(i);
}
}
catch {
// bad file - skip? could also try to remove the bad page:
blanks.Add(i);
}
}
return blanks.Count == info.FrameCount;
}
private bool IsBlankPage(AtalaImage image)
{
// you might want to configure the command to do noise removal and black border
// removal (or not) first.
BlankPageDetectionCommand command = new BlankPageDetectionCommand();
BlankPageDetectionResults results = command.Apply(image) as BlankPageDetectionResults;
return results.IsImageBlank;
}
private void RemoveBlanks(List<int> blanks, Stream source, Stream dest)
{
// blanks needs to be sorted low to high, which it will be if generated from
// above
TiffDocument doc = new TiffDocument(source);
int totalRemoved = 0;
foreach (int page in blanks) {
doc.Pages.RemoveAt(page - totalRemoved);
totalRemoved++;
}
doc.Save(dest);
}
你应该注意到空白页检测并不像“所有像素都是白色(-ish)?”那么简单。因为扫描引入了各种有趣的文物。要获取BlankPageDetectionCommand,您需要Document Imaging包。
答案 2 :(得分:0)
您是否有兴趣收缩文件或只是想避免人们浪费时间查看空白页?您只需将第二个IFD修补为0x00000000即可对文件进行快速而脏的编辑,以消除已知的空白页。这就是我的意思 - 如果你只是浏览页面,TIFF文件的布局很简单:
TIFF标头(4个字节) 第一个IFD偏移量(4个字节 - 通常指向0x00000008)
IFD:
标签数量(2字节)
{个别TIFF标签}(每个12字节)
下一个IFD偏移量(4个字节)
只需将“下一个IFD偏移量”修补为值0x00000000,即可“删除”超出当前页面的页面。