2

我需要从多页 TIFF 文件中删除一个页面。我目前在 .NET 中工作,但如果有人知道如何用该语言进行操作,我可以迁移到另一种语言。

该页面可以是倒数第二页,也可以是文件中的最后一页。而且我需要在不解压缩文件中的先前页面的情况下执行此操作,因此不要创建新的 TIFF 并复制我仍然想要的所有页面。

我已经有执行此操作的代码,但是由于我正在使用的 TIFF 文件大约 1.0 gb - 3.0 gb 被高度压缩,这非常耗时。如果我可以删除我想要的文件部分而不创建一个速度更快的新文件。

与文件的其余部分相比,我需要删除的页面非常小,可能在也可能不在它之后的页面也是如此,大约 500*500 像素。

我尝试过的,我尝试过 LibTiff.Net 库,在这里找到

http://bitmiracle.com/libtiff/

在搞砸了一段时间后,我向开发人员询问了我的问题,他们说目前不支持这样做。我也稍微研究了 ImageMagick,但我也无法弄清楚如何在那里做到这一点。

有人在这里有任何有用的想法吗?

4

1 回答 1

3

好的,有一个在 python 中工作的解决方案。

import mmap
from struct import *

def main():
    filename = raw_input("Input file name: ")
    f = open(filename, "r+b")
    offList, compList = getOffsets(f)
    for i in range(len(offList)):
        print "offset: ", offList[i], "\t Compression: ", compList[i]
    print "ran right"
    stripLabelAndMacro(f, offList, 3)
    offList, compList = getOffsets(f)
    for i in range(len(offList)):
        print "offset: ", offList[i], "\t Compression: ", compList[i]
    f.close()
    #test stripping end crap

def getOffsets(f):
    fmap = mmap.mmap(f.fileno(),0)
    offsets = []
    compressions = []
    #get TIFF version
    ver = int(unpack('H', fmap[2:4])[0])
    if ver == 42:
        #get first IDF
        offset = long(unpack('L', fmap[4:8])[0])
        while (offset != 0):
            offsets.append(offset)
            #get number of tags in this IDF
            tags = int(unpack('H', fmap[offset:offset+2])[0])
            i = 0
            while (i<tags):
                tagID = int(unpack('H',fmap[offset+2:offset+4])[0])
                #if the tag is a compression, get the compression SHORT value and
                #if recognized use a string representation
                if tagID == 259:
                    tagValue = int(unpack('H', fmap[offset+10:offset+12])[0])
                    if tagValue == 1:
                        compressions.append("None")
                    elif tagValue == 5:
                        compressions.append("LZW")
                    elif tagValue == 6:
                        compressions.append("JPEG")
                    elif tagValue == 7:
                        compressions.append("JPEG")
                    elif tagValue == 34712 or tagValue == 33003 or tagValue == 33005:
                        compressions.append("JP2K")
                    else:
                        compressions.append("Unknown")
                i+=1
                offset += 12

            offset = long(unpack('L', fmap[offset+2:offset+6])[0])
    return offsets, compressions

#Tested, Doesn't break TIFF
def stripLabel(f, offsetList, labelIndex):
    fmap = mmap.mmap(f.fileno(),0)
    offsetLabel = offsetList[labelIndex]
    offsetMacro = offsetList[labelIndex+1]
    offsetEnd = fmap.size()
    macroSize = offsetEnd - offsetMacro
    for i in range(macroSize):
        fmap[offsetLabel+i] = fmap[offsetMacro+i]
    fmap.flush()
    fmap.resize(offsetLabel+macroSize-1)
    fmap.close()

测试了一下,好像还不错。stripLabel 方法专门用于删除倒数第二个页面/目录并将最后一个向上移动,但理论上它应该适用于除最后一个以外的任何目录,并且可以轻松修改它以删除最后一个。它至少需要与您正在处理的文件大小相同的可用内存量,但它运行速度很快,并且文件大小对于大多数 TIFF 来说不是问题。这不是最优雅的方法,如果有人有另一种方法,请发布。

于 2011-03-10T15:06:22.450 回答