Удалить / Удалить страницу из многостраничного файла TIFF - PullRequest
2 голосов
/ 07 марта 2011

Мне нужно удалить страницу из многостраничного файла TIFF. В настоящее время я работаю в .NET, но могу перейти на другой язык, если кто-то знает, как это сделать на этом языке.

Страница будет либо второй, либо последней, либо последней страницей в файле. И мне нужно сделать это без распаковки предыдущих страниц в файле, чтобы не создавать новый TIFF и не копировать все страницы, которые я все еще хочу для этого.

У меня есть код, который уже делает это, но поскольку файлы TIFF, с которыми я работаю, сильно сжаты, примерно на 1,0–3,0 ГБ, это занимает очень много времени. Если я могу просто удалить ту часть файла, которая мне нужна, и не создавать новую, которая будет работать намного быстрее.

Страница, которую мне нужно удалить, очень мала по сравнению с остальной частью файла, так же как и страница, которая может или не может быть после нее, около 500 * 500 пикселей.

То, что я пробовал, я попробовал библиотеку LibTiff.Net, найденную здесь

http://bitmiracle.com/libtiff/

Поработав некоторое время, я спросил разработчика о моей проблеме, они сказали, что в настоящее время поддержки для этого нет. Я также немного изучил ImageMagick, но я так и не смог понять, как это сделать.

У кого-нибудь есть полезные идеи?

1 Ответ

3 голосов
/ 10 марта 2011

Хорошо, есть решение, работающее на 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.Это не самый элегантный подход, если у кого-то есть другой, пожалуйста, напишите.

...