python: ปรับปรุง multiple pages tif annotation

 

ต่อเนื่องจากครั้งก่อนเรื่อง imagemagick: ทำ annotate ไฟล์ tif

มีข้อบกพร่องเล็กน้อยคือ เวลาที่ inkscape นำเข้าไฟล์ tif จะกำหนดขนาดเป็นพิกเซลตามไฟล์ tif
ซึ่งจะมีขนาดใหญ่กว่า A4 พอสมควร (เทียบที่ค่าปริยายของ inkscape คือ 90dpi)
ถ้าจะแก้ไขด้วยการปรับหน้ากระดาษและลดขนาดภาพใน inkscape ทุกครั้ง ก็ดูไม่ค่อยสะดวก
และจะแก้ไขด้วยการลดขนาดพิกเซลของภาพ ก็เสียดายความละเอียด
จึงทดลองแปลงสคริปต์ไฟล์เดิม จากการใช้เชลล์สคริปต์ของ bash มาเป็นไพธอนแทน ทั้งนี้เพียงเพื่อหาขนาดพิกเซลของภาพเท่านั้น (แทบไม่ได้ใช้ความสามารถจริง ๆ ของไพธอนเลย)
วิธีการใช้แบบโกง ๆ หน่อย คือในครั้งแรกที่แตกไฟล์ เราสร้างไฟล์ svg ซึ่งเป็นไฟล์ xml ขึ้นมาเองเลย
โดยให้เขียนค่าพิกเซลที่เหมาะสม คือลดหรือเพิ่มขนาดให้ไฟล์ภาพลงบนความกว้างของหน้ากระดาษ A4 ได้

อย่าลืมต้องติดตั้งแพกเกจที่ต้องการก่อน
$ sudo aptitude install imagemagick inkscape evince python python-imaging

เนื้อไฟล์ตั้งชื่อว่า d.tifannotate.py มีดังนี้
$ sudo vi /usr/local/bin/d.tifannotate.py

#!/usr/bin/env python
# ANNOTATE MULTIPLE PAGES TIF FILE
# PREREQUISITE: inkscape imagemagick evince python-imaging

import sys
import os
import commands
try:
    import Image
except:
    print "Missing PIL library, require packages python-imaging."
    sys.exit(1)

#PARAMETER
overwrite_new_file = True    #OVERWRITE image-new.tif
__width = 744.09448819       #DEFAULT A4 SIZE IN PIXEL
__height = 1052.3622047      #

#REQUIRE PACKAGES
packages = ( ("inkscape","inkscape"), ("convert","imagemagick"), ("evince","evince") )
for i in range(len(packages)):
    exec("status, %s = commands.getstatusoutput('which %s')" % (packages[i][0], packages[i][0]) )
    if status != 0:
        print "Missing command %s, require packages %s." % (packages[i][0], packages[i][1],)
        sys.exit(1)

#GLOBAL VARS
err_open = "Cannot open file %s."

#PROCEDURE
def usage(progname):
    print "Annotate multiple pages TIF image."
    print "Usage: %s IMGFILE PAGES..." % (progname)
    print "Ex1  : %s image.tif 0 2 = Edit image.tif page 0 and page 2." % (progname)

def errmsg(msg, *arg):
    if not '%s' in msg:
        return msg
    if type(arg)!=type([]):
        return msg % (arg)
    lmsg = msg.split('%s')
    for i in range(len(arg)):
        lmsg[1] = lmsg[0] + str(arg[i]) + lmsg[1]
        lmsg.pop(0)
    return '%s'.join(lmsg)

def genfilename(filename="",tail="new",overwrite=True):
    if filename=="":
        return ""
    if tail.lower()=="new":
        tail="new"
    if tail.lower()!="new" and tail.lower()!="bak":
        tail="bak"
    name,ext = os.path.splitext(filename)
    if not overwrite and os.path.exists(name+'-'+tail+ext):
        i=0
        while os.path.exists(name+'-'+tail+str(i)+ext) and (i < 1000):
            i=i+1
        if i>999:
            return ""
        return name+"-"+tail+str(i)+ext
    else:
        return name+'-'+tail+ext

def createsvg(tifname):
    img = Image.open(tifname)
    width, height = img.size
    newwidth = __width
    newheight = float(height)/width*newwidth
    file, ext = os.path.splitext(tifname)
    f = open(file+'.svg', 'w')
    f.write("""\
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.0"
   width="%s"
   height="%s"
   id="svg2">
  <defs
     id="defs5" />
  <image
     xlink:href="%s"
     x="0"
     y="0"
     width="%s"
     height="%s"
     id="image9" />
</svg>""" % (__width, __height, tifname, newwidth, newheight,))
    f.close()
    return

#MAIN PROGRAM
def main(tiffile, pages):
    newfile=genfilename(tiffile,"new",overwrite_new_file)
    if newfile=="":
         print "Cannot save backup file."
         sys.exit(1)

    #SPLIT FILE
    name,ext = os.path.splitext(tiffile)
    dirname = name+'~'
    if not os.path.exists(dirname):
		os.mkdir(dirname)
    if not os.path.exists(os.path.join(dirname, name+'0'+ext)):
        os.system('%s %s %s' % (convert, tiffile, os.path.join(dirname,name)) +'%d'+ ext)

    #CREATE svg FILE IN SUBDIR
    os.chdir(dirname)
    filelist = [i for i in os.listdir(os.path.curdir) if i[-(len(ext)):]==ext ]
    for i in filelist:
        n,e = os.path.splitext(i)
        c = n+'.svg'
        if not os.path.exists(c):
            createsvg(i)

    #EDIT/ADD ANNOTATE
    for i in pages:
        if int(i) < len(filelist):
            c = str(i)
            os.system('%s %s.svg' % (inkscape, name+c,))
            os.system('%s -e %s.png %s.svg' % (inkscape, name+c, name+c,)) 
        else:
            print "Invalid page %s." % (i,)
    #MERGE BACK TO NEW NAME:convert img0.svg ... -adjoin -compress lzw ../img-new.tif
    allfile = ' '.join( [i for i in os.listdir(os.path.curdir) if i[-(4):]=='.png' ] )
    os.system('%s %s -adjoin -compress lzw %s' % (convert, allfile, os.path.join(os.path.pardir,newfile), ))
    #CHDIR BACK
    os.chdir(os.path.pardir)
    print "Annotate %s success, save new file in %s. Viewing with %s" % (tiffile,newfile,evince)
    os.system('%s %s' % (evince, newfile,))
    

if __name__=="__main__":
    #sys.argv=[progname tiffile 0 1 2]
    progname=os.path.basename(sys.argv[0])
    try:
         tiffile=sys.argv[1]
    except:
         usage(progname)
         sys.exit(1)
    if not os.path.isfile(tiffile):
         print errmsg(err_open, tiffile)
         sys.exit(1)
    if len(sys.argv)<3:
         usage(progname)
         sys.exit(1)
    pages = sys.argv[2:]
    main(tiffile, pages)

เรียกใช้เหมือนเดิมคือ
$ d.tifannotate.py IMAGE.tif 0 1
ได้ผลออกมาเป็น IMAGE-new.tif

หมายเหตุ
ถ้าต้องการพิมพ์จาก inkscape ต้องติดตั้งแพกเกจ cupsys-bsd ด้วย
$ sudo aptitude install cupsys-bsd

update 50-09-11

  • แก้บั๊กเรื่องตรวจสอบชื่อไฟล์
  • แก้บั๊ก convert แปลงฟอนต์ไทยไม่ตรง ด้วยการส่งออกจาก inkscape เป็น png ก่อน
 

Syndicate

Subscribe to Syndicate

Who's online

There are currently 0 users online.