123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #!/usr/bin/env python
- import cStringIO
- import struct
- import os, os.path
- from pdftypes import LITERALS_DCT_DECODE
- from pdfcolor import LITERAL_DEVICE_GRAY, LITERAL_DEVICE_RGB, LITERAL_DEVICE_CMYK
- def align32(x):
- return ((x+3)//4)*4
- ## BMPWriter
- ##
- class BMPWriter(object):
- def __init__(self, fp, bits, width, height):
- self.fp = fp
- self.bits = bits
- self.width = width
- self.height = height
- if bits == 1:
- ncols = 2
- elif bits == 8:
- ncols = 256
- elif bits == 24:
- ncols = 0
- else:
- raise ValueError(bits)
- self.linesize = align32((self.width*self.bits+7)//8)
- self.datasize = self.linesize * self.height
- headersize = 14+40+ncols*4
- info = struct.pack('<IiiHHIIIIII', 40, self.width, self.height, 1, self.bits, 0, self.datasize, 0, 0, ncols, 0)
- assert len(info) == 40, len(info)
- header = struct.pack('<ccIHHI', 'B', 'M', headersize+self.datasize, 0, 0, headersize)
- assert len(header) == 14, len(header)
- self.fp.write(header)
- self.fp.write(info)
- if ncols == 2:
- # B&W color table
- for i in (0, 255):
- self.fp.write(struct.pack('BBBx', i, i, i))
- elif ncols == 256:
- # grayscale color table
- for i in xrange(256):
- self.fp.write(struct.pack('BBBx', i, i, i))
- self.pos0 = self.fp.tell()
- self.pos1 = self.pos0 + self.datasize
- return
- def write_line(self, y, data):
- self.fp.seek(self.pos1 - (y+1)*self.linesize)
- self.fp.write(data)
- return
- ## ImageWriter
- ##
- class ImageWriter(object):
- def __init__(self, outdir):
- self.outdir = outdir
- if not os.path.exists(self.outdir):
- os.makedirs(self.outdir)
- return
- def export_image(self, image):
- stream = image.stream
- filters = stream.get_filters()
- (width, height) = image.srcsize
- if len(filters) == 1 and filters[0] in LITERALS_DCT_DECODE:
- ext = '.jpg'
- elif (image.bits == 1 or
- image.bits == 8 and image.colorspace in (LITERAL_DEVICE_RGB, LITERAL_DEVICE_GRAY)):
- ext = '.%dx%d.bmp' % (width, height)
- else:
- ext = '.%d.%dx%d.img' % (image.bits, width, height)
- name = image.name+ext
- path = os.path.join(self.outdir, name)
- fp = file(path, 'wb')
- if ext == '.jpg':
- raw_data = stream.get_rawdata()
- if LITERAL_DEVICE_CMYK in image.colorspace:
- from PIL import Image
- from PIL import ImageChops
- ifp = cStringIO.StringIO(raw_data)
- i = Image.open(ifp)
- i = ImageChops.invert(i)
- i = i.convert('RGB')
- i.save(fp, 'JPEG')
- else:
- fp.write(raw_data)
- elif image.bits == 1:
- bmp = BMPWriter(fp, 1, width, height)
- data = stream.get_data()
- i = 0
- width = (width+7)//8
- for y in xrange(height):
- bmp.write_line(y, data[i:i+width])
- i += width
- elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_RGB:
- bmp = BMPWriter(fp, 24, width, height)
- data = stream.get_data()
- i = 0
- width = width*3
- for y in xrange(height):
- bmp.write_line(y, data[i:i+width])
- i += width
- elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_GRAY:
- bmp = BMPWriter(fp, 8, width, height)
- data = stream.get_data()
- i = 0
- for y in xrange(height):
- bmp.write_line(y, data[i:i+width])
- i += width
- else:
- fp.write(stream.get_data())
- fp.close()
- return name
|