def _save(im, fp, filename): if _imaging_gif: # call external driver try: _imaging_gif.save(im, fp, filename) return except IOError: pass # write uncompressed file try: rawmode = RAWMODE[im.mode] imOut = im except KeyError: # convert on the fly (EXPERIMENTAL -- I'm not sure PIL # should automatically convert images on save...) if Image.getmodebase(im.mode) == "RGB": imOut = im.convert("P") rawmode = "P" else: imOut = im.convert("L") rawmode = "L" # header for s in getheader(imOut, im.encoderinfo): fp.write(s) flags = 0 try: interlace = im.encoderinfo["interlace"] except: # default is on (since we're writing uncompressed images) interlace = 1 flags = flags | 64 # local image header fp.write( "," + o16(0) + o16(0) + o16(im.size[0]) + o16(im.size[1]) + chr(flags) + chr(8) # bounding box # size # flags ) # bits imOut.encoderconfig = (8, interlace) ImageFile._save(imOut, fp, [("gif", (0, 0) + im.size, 0, rawmode)]) fp.write("\0") # end of image data fp.write(";") # end of file try: fp.flush() except: pass
def getdata(im, offset = (0, 0), **params): """Return a list of strings representing this image. The first string is a local image header, the rest contains encoded image data.""" class collector: data = [] def write(self, data): self.data.append(data) im.load() # make sure raster data is available fp = collector() try: im.encoderinfo = params # local image header fp.write("," + o16(offset[0]) + # offset o16(offset[1]) + o16(im.size[0]) + # size o16(im.size[1]) + chr(0) + # flags chr(8)) # bits ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])]) fp.write("\0") # end of image data finally: del im.encoderinfo return fp.data
def _save(im, fp, filename, check=0): try: type, rawmode = SAVE[im.mode] except KeyError: raise ValueError, "Cannot save %s images as IM" % im.mode try: frames = im.encoderinfo["frames"] except KeyError: frames = 1 if check: return check fp.write("Image type: %s image\r\n" % type) if filename: fp.write("Name: %s\r\n" % filename) fp.write("Image size (x*y): %d*%d\r\n" % im.size) fp.write("File size (no of images): %d\r\n" % frames) if im.mode == "P": fp.write("Lut: 1\r\n") fp.write("\000" * (511 - fp.tell()) + "\032") if im.mode == "P": fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))])
def getdata(im, offset=(0, 0), **params): """Return a list of strings representing this image. The first string is a local image header, the rest contains encoded image data.""" class collector: data = [] def write(self, data): self.data.append(data) im.load() # make sure raster data is available fp = collector() try: im.encoderinfo = params # local image header fp.write("," + o16(offset[0]) + # offset o16(offset[1]) + o16(im.size[0]) + # size o16(im.size[1]) + chr(0) + # flags chr(8)) # bits ImageFile._save(im, fp, [("gif", (0, 0) + im.size, 0, RAWMODE[im.mode])]) fp.write("\0") # end of image data finally: del im.encoderinfo return fp.data
def _save(im, fp, filename): if im.mode != "1": raise IOError, "cannot write mode %s as MSP" % im.mode # create MSP header header = [0] * 16 header[0], header[1] = i16("Da"), i16("nM") # version 1 header[2], header[3] = im.size header[4], header[5] = 1, 1 header[6], header[7] = 1, 1 header[8], header[9] = im.size sum = 0 for h in header: sum = sum ^ h header[12] = sum # FIXME: is this the right field? # header for h in header: fp.write(o16(h)) # image body ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 32, ("1", 0, 1))])
def _save(im, fp, filename, check=0): try: rawmode, bits, colormaptype, imagetype = SAVE[im.mode] except KeyError: raise IOError("cannot write mode %s as TGA" % im.mode) if check: return check if colormaptype: colormapfirst, colormaplength, colormapentry = 0, 256, 24 else: colormapfirst, colormaplength, colormapentry = 0, 0, 0 if im.mode == "RGBA": flags = 8 else: flags = 0 orientation = im.info.get("orientation", -1) if orientation > 0: flags = flags | 0x20 fp.write("\000" + chr(colormaptype) + chr(imagetype) + o16(colormapfirst) + o16(colormaplength) + chr(colormapentry) + o16(0) + o16(0) + o16(im.size[0]) + o16(im.size[1]) + chr(bits) + chr(flags)) if colormaptype: fp.write(im.im.getpalette("RGB", "BGR")) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))])
def _save(im, fp, filename, check=0): try: type, rawmode = SAVE[im.mode] except KeyError: raise ValueError, "Cannot save %s images as IM" % im.mode try: frames = im.encoderinfo["frames"] except KeyError: frames = 1 if check: return check fp.write("Image type: %s image\r\n" % type) if filename: fp.write("Name: %s\r\n" % filename) fp.write("Image size (x*y): %d*%d\r\n" % im.size) fp.write("File size (no of images): %d\r\n" % frames) if im.mode == "P": fp.write("Lut: 1\r\n") fp.write("\000" * (511-fp.tell()) + "\032") if im.mode == "P": fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
def _save(im, fp, filename): if im.mode != "1": raise IOError, "cannot write mode %s as MSP" % im.mode # create MSP header header = [0] * 16 header[0], header[1] = i16("Da"), i16("nM") # version 1 header[2], header[3] = im.size header[4], header[5] = 1, 1 header[6], header[7] = 1, 1 header[8], header[9] = im.size sum = 0 for h in header: sum = sum ^ h header[12] = sum # FIXME: is this the right field? # header for h in header: fp.write(o16(h)) # image body ImageFile._save(im, fp, [("raw", (0,0)+im.size, 32, ("1", 0, 1))])
def saveStack(imstack, filename): hdr_stack = makeSpiderHeaderOverall(imstack) if len(hdr_stack) < 256: raise IOError, "Error creating Spider 2D stack header" # write the SPIDER header try: fp = open(filename, 'wb') except: raise IOError, "Unable to open %s for writing" % filename fp.writelines(hdr_stack) rawmode = "F;32NF" #32-bit native floating point ct = 0 for im in imstack: ct += 1 # numbering of stacked images if im.mode[0] != "F": im = im.convert('F') hdr = makeSpiderHeaderInStack(im, ct) # h[27]=ct if len(hdr) < 256: raise IOError, "Error creating Spider header" fp.writelines(hdr) #ims = im.tostring() #fp.write(ims) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))]) fp.close()
def _save(im, fp, filename, check=0): try: type, rawmode = SAVE[im.mode] except KeyError: raise ValueError("Cannot save {0} images as IM".format(im.mode)) try: frames = im.encoderinfo["frames"] except KeyError: frames = 1 if check: return check data = [] data.append("Image type: {0} image\r\n".format(type)) if filename: data.append("Name: {0}\r\n".format(filename)) data.append("Image size (x*y): {size[0]}*{size[1]}\r\n".format(size=im.size)) data.append("File size (no of images): {0}\r\n".format(frames)) if im.mode == "P": data.append("Lut: 1\r\n") fp.write(''.join(data).encode('latin_1', errors='replace')) fp.write(b"\x00" * (511-fp.tell()) + b"\x1a") if im.mode == "P": fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
def _save(im, fp, filename): try: rawmode = RAWMODE[im.mode] except KeyError: raise IOError("cannot write mode %s as JPEG" % im.mode) info = im.encoderinfo dpi = info.get("dpi", (0, 0)) # get keyword arguments im.encoderconfig = ( info.get("quality", 0), # "progressive" is the official name, but older documentation # says "progression" # FIXME: issue a warning if the wrong form is used (post-1.1.5) info.has_key("progressive") or info.has_key("progression"), info.get("smooth", 0), info.has_key("optimize"), info.get("streamtype", 0), dpi[0], dpi[1] ) ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
def _save(im, fp, filename): try: rawmode = RAWMODE[im.mode] except KeyError: raise IOError("cannot write mode %s as JPEG" % im.mode) info = im.encoderinfo dpi = info.get("dpi", (0, 0)) # get keyword arguments im.encoderconfig = ( info.get("quality", 0), # "progressive" is the official name, but older documentation # says "progression" # FIXME: issue a warning if the wrong form is used (post-1.1.5) info.has_key("progressive") or info.has_key("progression"), info.get("smooth", 0), info.has_key("optimize"), info.get("streamtype", 0), dpi[0], dpi[1]) ImageFile._save(im, fp, [("jpeg", (0, 0) + im.size, 0, rawmode)])
def _save(im, fp, filename): if im.mode != "RGB": raise IOError("cannot write mode %s as WEBP" % im.mode) im.encoderconfig = ( im.encoderinfo.get("quality", 0), ) ImageFile._save(im, fp, [("webp", (0, 0) + im.size, 0, (im.mode,))])
def _save(im, fp, filename, check=0): try: version, bits, planes, rawmode = SAVE[im.mode] except KeyError: raise ValueError, "Cannot save %s images as PCX" % im.mode if check: return check # bytes per plane stride = (im.size[0] * bits + 7) / 8 # under windows, we could determine the current screen size with # "Image.core.display_mode()[1]", but I think that's overkill... screen = im.size dpi = 100, 100 # PCX header fp.write( chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) + o16(0) + o16(im.size[0] - 1) + o16(im.size[1] - 1) + o16(dpi[0]) + o16(dpi[1]) + chr(0) * 24 + chr(255) * 24 + chr(0) + chr(planes) + o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) + chr(0) * 54 ) assert fp.tell() == 128 ImageFile._save(im, fp, [("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))]) if im.mode == "P": # colour palette fp.write(chr(12)) fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes elif im.mode == "L": # greyscale palette fp.write(chr(12)) for i in range(256): fp.write(chr(i) * 3)
def _save(im, fp, filename, eps=1): """EPS Writer for the Python Imaging Library.""" # # make sure image data is available im.load() # # determine postscript image mode if im.mode == "L": operator = (8, 1, "image") elif im.mode == "RGB": operator = (8, 3, "false 3 colorimage") elif im.mode == "CMYK": operator = (8, 4, "false 4 colorimage") else: raise ValueError("image mode is not supported") if eps: # # write EPS header fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") #fp.write("%%CreationDate: %s"...) fp.write("%%BoundingBox: 0 0 {0[0]} {0[1]}\n".format(im.size).encode( 'latin_1', errors='replace')) fp.write(b"%%Pages: 1\n") fp.write(b"%%EndComments\n") fp.write(b"%%Page: 1 1\n") fp.write("%%ImageData: {0[0]} {0[1]}".format(im.size).encode('latin_1', errors='replace')) fp.write("{0[0]} {0[1]} 0 1 1 \"{0[2]}\"\n".format(operator).encode( 'latin_1', errors='replace')) # # image header fp.write(b"gsave\n") fp.write(b"10 dict begin\n") fp.write("/buf {0} string def\n".format(im.size[0]*operator[1]).encode( 'latin_1', errors='replace')) fp.write("{0[0]} {0[1]} scale\n".format(im.size).encode('latin_1', errors='replace')) fp.write("{0[0]} {0[1]} 8\n".format(im.size).encode('latin_1', errors='replace')) # <= bits fp.write("[{0[0]} 0 0 -{0[1]} 0 {0[1]}]\n".format(im.size).encode( 'latin_1', errors='replace')) fp.write(b"{ currentfile buf readhexstring pop } bind\n") fp.write("{0[2]}\n".format(operator).encode('latin_1', errors='replace')) ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)]) fp.write(b"\n%%EndBinary\n") fp.write(b"grestore end\n") fp.flush()
def _save(im, fp, filename): try: rawmode = RAWMODE[im.mode] except KeyError: raise IOError("cannot write mode %s as JPEG" % im.mode) info = im.encoderinfo dpi = info.get("dpi", (0, 0)) subsampling = info.get("subsampling", -1) if subsampling == "4:4:4": subsampling = 0 elif subsampling == "4:2:2": subsampling = 1 elif subsampling == "4:1:1": subsampling = 2 extra = "" icc_profile = info.get("icc_profile") if icc_profile: ICC_OVERHEAD_LEN = 14 MAX_BYTES_IN_MARKER = 65533 MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN markers = [] while icc_profile: markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER]) icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:] i = 1 for marker in markers: size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker)) extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker) i = i + 1 # get keyword arguments im.encoderconfig = ( info.get("quality", 0), # "progressive" is the official name, but older documentation # says "progression" # FIXME: issue a warning if the wrong form is used (post-1.1.7) info.has_key("progressive") or info.has_key("progression"), info.get("smooth", 0), info.has_key("optimize"), info.get("streamtype", 0), dpi[0], dpi[1], subsampling, extra, ) ImageFile.MAXBLOCK = 10000000 ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
def _save(im, fp, filename): try: rawmode = RAWMODE[im.mode] except KeyError: raise IOError("cannot write mode %s as JPEG" % im.mode) info = im.encoderinfo dpi = info.get("dpi", (0, 0)) subsampling = info.get("subsampling", -1) if subsampling == "4:4:4": subsampling = 0 elif subsampling == "4:2:2": subsampling = 1 elif subsampling == "4:1:1": subsampling = 2 extra = "" icc_profile = info.get("icc_profile") if icc_profile: ICC_OVERHEAD_LEN = 14 MAX_BYTES_IN_MARKER = 65533 MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN markers = [] while icc_profile: markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER]) icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:] i = 1 for marker in markers: size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker)) extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker) i = i + 1 # get keyword arguments im.encoderconfig = ( info.get("quality", 0), # "progressive" is the official name, but older documentation # says "progression" # FIXME: issue a warning if the wrong form is used (post-1.1.7) info.has_key("progressive") or info.has_key("progression"), info.get("smooth", 0), info.has_key("optimize"), info.get("streamtype", 0), dpi[0], dpi[1], subsampling, extra, ) ImageFile._save(im, fp, [("jpeg", (0, 0) + im.size, 0, rawmode)])
def _save(im, fp, filename, eps=1): """EPS Writer for the Python Imaging Library.""" # # make sure image data is available im.load() # # determine postscript image mode if im.mode == "L": operator = (8, 1, "image") elif im.mode == "RGB": operator = (8, 3, "false 3 colorimage") elif im.mode == "CMYK": operator = (8, 4, "false 4 colorimage") else: raise ValueError("image mode is not supported") if eps: # # write EPS header fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") #fp.write(b"%%CreationDate: %s"...) fp.write( bytes("%%%%BoundingBox: 0 0 %d %d\n" % im.size, encoding='ascii')) fp.write(b"%%Pages: 1\n") fp.write(b"%%EndComments\n") fp.write(b"%%Page: 1 1\n") fp.write(bytes("%%ImageData: %d %d " % im.size, encoding='ascii')) fp.write(bytes("%d %d 0 1 1 \"%s\"\n" % operator, encoding='ascii')) # # image header fp.write(b"gsave\n") fp.write(b"10 dict begin\n") fp.write( bytes("/buf %d string def\n" % (im.size[0] * operator[1]), encoding='ascii')) fp.write(bytes("%d %d scale\n" % im.size, encoding='ascii')) fp.write(bytes("%d %d 8\n" % im.size, encoding='ascii')) # <= bits fp.write( bytes("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]), encoding='ascii')) fp.write(b"{ currentfile buf readhexstring pop } bind\n") fp.write(bytes("%s\n" % operator[2], encoding='ascii')) ImageFile._save(im, fp, [("eps", (0, 0) + im.size, 0, None)]) fp.write(b"\n%%%%EndBinary\n") fp.write(b"grestore end\n") fp.flush()
def _save(im, fp, filename, check=0): try: version, bits, planes, rawmode = SAVE[im.mode] except KeyError: raise ValueError("Cannot save %s images as WBMP" % im.mode) if check: return check width, height = im.size # Write header fp.write (chr(0) + chr(0) + _tomb(width) + _tomb(height)) # Write data ImageFile._save(im, fp, [("raw", (0,0) + im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename, check=0): try: version, bits, planes, rawmode = SAVE[im.mode] except KeyError: raise ValueError("Cannot save %s images as WBMP" % im.mode) if check: return check width, height = im.size # Write header fp.write(chr(0) + chr(0) + _tomb(width) + _tomb(height)) # Write data ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename, eps=1): """EPS Writer for the Python Imaging Library.""" # # make sure image data is available im.load() # # determine postscript image mode if im.mode == "L": operator = (8, 1, "image") elif im.mode == "RGB": operator = (8, 3, "false 3 colorimage") elif im.mode == "CMYK": operator = (8, 4, "false 4 colorimage") else: raise ValueError("image mode is not supported") if eps: # # write EPS header fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") #fp.write(b"%%CreationDate: %s"...) fp.write(bytes("%%%%BoundingBox: 0 0 %d %d\n" % im.size, encoding='ascii')) fp.write(b"%%Pages: 1\n") fp.write(b"%%EndComments\n") fp.write(b"%%Page: 1 1\n") fp.write(bytes("%%ImageData: %d %d " % im.size, encoding='ascii')) fp.write(bytes("%d %d 0 1 1 \"%s\"\n" % operator, encoding='ascii')) # # image header fp.write(b"gsave\n") fp.write(b"10 dict begin\n") fp.write(bytes("/buf %d string def\n" % (im.size[0] * operator[1]), encoding='ascii')) fp.write(bytes("%d %d scale\n" % im.size, encoding='ascii')) fp.write(bytes("%d %d 8\n" % im.size, encoding='ascii')) # <= bits fp.write(bytes("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]), encoding='ascii')) fp.write(b"{ currentfile buf readhexstring pop } bind\n") fp.write(bytes("%s\n" % operator[2], encoding='ascii')) ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)]) fp.write(b"\n%%%%EndBinary\n") fp.write(b"grestore end\n") fp.flush()
def _save(im, fp, filename): if im.mode == "1": rawmode, head = "1;I", "P4" elif im.mode == "L": rawmode, head = "L", "P5" elif im.mode == "RGB": rawmode, head = "RGB", "P6" elif im.mode == "RGBA": rawmode, head = "RGB", "P6" else: raise IOError, "cannot write mode %s as PPM" % im.mode fp.write(head + "\n%d %d\n" % im.size) if head != "P4": fp.write("255\n") ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename): if im.mode == "1": rawmode, head = "1;I", b"P4" elif im.mode == "L": rawmode, head = "L", b"P5" elif im.mode == "RGB": rawmode, head = "RGB", b"P6" elif im.mode == "RGBA": rawmode, head = "RGB", b"P6" else: raise IOError("cannot write mode %s as PPM" % im.mode) fp.write(head + bytes("\n%d %d\n" % im.size, encoding='ascii')) if head != b"P4": fp.write(b"255\n") ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename): if im.mode == "1": rawmode, head = "1;I", "P4" elif im.mode == "L": rawmode, head = "L", "P5" elif im.mode == "RGB": rawmode, head = "RGB", "P6" elif im.mode == "RGBA": rawmode, head = "RGB", "P6" else: raise IOError, "cannot write mode %s as PPM" % im.mode fp.write(head + "\n%d %d\n" % im.size) if head != "P4": fp.write("255\n") ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename): if im.mode == "1": rawmode, head = "1;I", "P4" elif im.mode == "L": rawmode, head = "L", "P5" elif im.mode == "RGB": rawmode, head = "RGB", "P6" elif im.mode == "RGBA": rawmode, head = "RGB", "P6" else: raise IOError("cannot write mode {0} as PPM".format(im.mode)) fp.write(head + "\n{0} {1}\n".format(*im.size).encode('latin_1', errors='replace')) if head != "P4": fp.write(b"255\n") ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
def _save(im, fp, filename, check=0): try: rawmode, bits, colors = SAVE[im.mode] except KeyError: raise IOError("cannot write mode %s as BMP" % im.mode) if check: return check stride = ((im.size[0] * bits + 7) / 8 + 3) & (~3) header = 40 # or 64 for OS/2 version 2 offset = 14 + header + colors * 4 image = stride * im.size[1] # bitmap header fp.write("BM" + # file type (magic) o32(offset + image) + # file size o32(0) + # reserved o32(offset)) # image data offset # bitmap info header fp.write( o32(header) + # info header size o32(im.size[0]) + # width o32(im.size[1]) + # height o16(1) + # planes o16(bits) + # depth o32(0) + # compression (0=uncompressed) o32(image) + # size of bitmap o32(1) + o32(1) + # resolution o32(colors) + # colors used o32(colors)) # colors important fp.write("\000" * (header - 40)) # padding (for OS/2 format) if im.mode == "1": for i in (0, 255): fp.write(chr(i) * 4) elif im.mode == "L": for i in range(256): fp.write(chr(i) * 4) elif im.mode == "P": fp.write(im.im.getpalette("RGB", "BGRX")) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))])
def _save(im, fp, filename, check=0): try: rawmode, bits, colors = SAVE[im.mode] except KeyError: raise IOError("cannot write mode %s as BMP" % im.mode) if check: return check stride = ((im.size[0] * bits + 7) / 8 + 3) & (~3) header = 40 # or 64 for OS/2 version 2 offset = 14 + header + colors * 4 image = stride * im.size[1] # bitmap header fp.write( "BM" + o32(offset + image) + o32(0) + o32(offset) # file type (magic) # file size # reserved ) # image data offset # bitmap info header fp.write( o32(header) + o32(im.size[0]) # info header size + o32(im.size[1]) # width + o16(1) # height + o16(bits) # planes + o32(0) # depth + o32(image) # compression (0=uncompressed) + o32(1) # size of bitmap + o32(1) + o32(colors) # resolution + o32(colors) # colors used ) # colors important fp.write("\000" * (header - 40)) # padding (for OS/2 format) if im.mode == "1": for i in (0, 255): fp.write(chr(i) * 4) elif im.mode == "L": for i in range(256): fp.write(chr(i) * 4) elif im.mode == "P": fp.write(im.im.getpalette("RGB", "BGRX")) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))])
def _save(im, fp, filename, check=0): # check if im.mode is compatible with MRC (see Bmp...) if check: return check header = MrcHeader() header['width'] = im.size[0] header['height'] = im.size[1] header['depth'] = 1 header['mode'] = pilmode_mrcmode[im.mode] header.tofile(fp) rawmode = mrcmode_rawmode[header['mode']] tile = [("raw", (0,0)+im.size, header.headerlen, (rawmode, 0, 1))] print 'savetile:', tile ImageFile._save(im, fp, tile)
def _save(im, fp, filename, check=0): # check if im.mode is compatible with MRC (see Bmp...) if check: return check header = MrcHeader() header['width'] = im.size[0] header['height'] = im.size[1] header['depth'] = 1 header['mode'] = pilmode_mrcmode[im.mode] header.tofile(fp) rawmode = mrcmode_rawmode[header['mode']] tile = [("raw", (0, 0) + im.size, header.headerlen, (rawmode, 0, 1))] print 'savetile:', tile ImageFile._save(im, fp, tile)
def _save(im, fp, filename): if im.mode != "1": raise IOError, "cannot write mode %s as XBM" % im.mode fp.write("#define im_width %d\n" % im.size[0]) fp.write("#define im_height %d\n" % im.size[1]) hotspot = im.encoderinfo.get("hotspot") if hotspot: fp.write("#define im_x_hot %d\n" % hotspot[0]) fp.write("#define im_y_hot %d\n" % hotspot[1]) fp.write("static char im_bits[] = {\n") ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)]) fp.write("};\n")
def _save(im, fp, filename): if im.mode != "1": raise IOError, "cannot write mode %s as XBM" % im.mode fp.write("#define im_width %d\n" % im.size[0]) fp.write("#define im_height %d\n" % im.size[1]) hotspot = im.encoderinfo.get("hotspot") if hotspot: fp.write("#define im_x_hot %d\n" % hotspot[0]) fp.write("#define im_y_hot %d\n" % hotspot[1]) fp.write("static char im_bits[] = {\n") ImageFile._save(im, fp, [("xbm", (0, 0) + im.size, 0, None)]) fp.write("};\n")
def _save(im, fp, filename): try: rawmode = RAWMODE[im.mode] except KeyError: raise IOError, "cannot write mode %s as JPEG" % im.mode dpi = _fetch(im.encoderinfo, "dpi", (0, 0)) # get keyword arguments im.encoderconfig = (_fetch(im.encoderinfo, "quality", 0), im.encoderinfo.has_key("progressive"), _fetch(im.encoderinfo, "smooth", 0), im.encoderinfo.has_key("optimize"), _fetch(im.encoderinfo, "streamtype", 0), dpi[0], dpi[1]) ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
def _save(im, fp, filename): if im.mode[0] != "F": im = im.convert('F') hdr = makeSpiderHeader(im) if len(hdr) < 256: raise IOError, "Error creating Spider header" # write the SPIDER header try: fp = open(filename, 'wb') except: raise IOError, "Unable to open %s for writing" % filename fp.writelines(hdr) rawmode = "F;32NF" # 32-bit native floating point ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))]) fp.close()
def _save(im, fp, filename, check=0): try: version, bits, planes, rawmode = SAVE[im.mode] except KeyError: raise ValueError, "Cannot save %s images as PCX" % im.mode if check: return check # bytes per plane stride = (im.size[0] * bits + 7) / 8 # under windows, we could determine the current screen size with # "Image.core.display_mode()[1]", but I think that's overkill... screen = im.size dpi = 100, 100 # PCX header fp.write( chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) + o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) + o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) + o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) + chr(0)*54 ) assert fp.tell() == 128 ImageFile._save(im, fp, [("pcx", (0, 0) + im.size, 0, (rawmode, bits*planes))]) if im.mode == "P": # colour palette fp.write(chr(12)) fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes elif im.mode == "L": # greyscale palette fp.write(chr(12)) for i in range(256): fp.write(chr(i)*3)
def _save(im, fp, filename): if im.mode[0] != "F": im = im.convert('F') hdr = makeSpiderHeader(im) if len(hdr) < 256: raise IOError, "Error creating Spider header" # write the SPIDER header try: fp = open(filename, 'wb') except: raise IOError, "Unable to open %s for writing" % filename fp.writelines(hdr) rawmode = "F;32NF" #32-bit native floating point ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode,0,1))]) fp.close()
def _save(im, fp, filename, check=0): try: rawmode, bits, colormaptype, imagetype = SAVE[im.mode] except KeyError: raise IOError("cannot write mode %s as TGA" % im.mode) if check: return check if colormaptype: colormapfirst, colormaplength, colormapentry = 0, 256, 24 else: colormapfirst, colormaplength, colormapentry = 0, 0, 0 if im.mode == "RGBA": flags = 8 else: flags = 0 orientation = im.info.get("orientation", -1) if orientation > 0: flags = flags | 0x20 fp.write("\000" + chr(colormaptype) + chr(imagetype) + o16(colormapfirst) + o16(colormaplength) + chr(colormapentry) + o16(0) + o16(0) + o16(im.size[0]) + o16(im.size[1]) + chr(bits) + chr(flags)) if colormaptype: fp.write(im.im.getpalette("RGB", "BGR")) ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, orientation))])
def _save(im, fp, filename): if im.mode != "1": raise IOError("cannot write mode {0} as XBM".format(im.mode)) data = [] data.append("#define im_width {0}\n".format(im.size[0])) data.append("#define im_height {0}\n".format(im.size[1])) hotspot = im.encoderinfo.get("hotspot") if hotspot: data.append("#define im_x_hot {0}\n".format(hotspot[0])) data.append("#define im_y_hot {0}\n".format(hotspot[1])) data.append("static char im_bits[] = {\n") data = ''.join(data).encode('latin_1', errors='replace') ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)]) fp.write(b"};\n")
def _save(im, fp, filename, chunk=putchunk, check=0, pnginfo=None): # save an image to disk (called by the save method) print "calling our _save" mode = im.mode # we hack around encoderinfo... im.encoderinfo = {} if mode == "P": # # attempt to minimize storage requirements for palette images if im.encoderinfo.has_key("bits"): # number of bits specified by user n = 1 << im.encoderinfo["bits"] else: # check palette contents n = 256 # FIXME if n <= 2: bits = 1 elif n <= 4: bits = 2 elif n <= 16: bits = 4 else: bits = 8 if bits != 8: mode = "%s;%d" % (mode, bits) # encoder options if im.encoderinfo.has_key("dictionary"): dictionary = im.encoderinfo["dictionary"] else: dictionary = "" im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary) # get the corresponding PNG mode try: rawmode, mode = _OUTMODES[mode] except KeyError: raise IOError, "cannot write mode %s as PNG" % mode if check: return check # # write minimal PNG file fp.write(_MAGIC) chunk( fp, "IHDR", o32(im.size[0]), o32(im.size[1]), # 0: size mode, # 8: depth/type chr(0), # 10: compression chr(0), # 11: filter category chr(0), ) # 12: interlace flag if im.mode == "P": chunk(fp, "PLTE", im.im.getpalette("RGB")) if im.encoderinfo.has_key("transparency"): if im.mode == "P": transparency = max(0, min(255, im.encoderinfo["transparency"])) chunk(fp, "tRNS", chr(255) * transparency + chr(0)) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, "tRNS", o16(transparency)) else: raise IOError, "cannot use transparency for this mode" if 0: # FIXME: to be supported some day chunk(fp, "gAMA", o32(int(gamma * 100000.0))) # info = im.encoderinfo.get("pnginfo") info = pnginfo if info: for cid, data in info.chunks: chunk(fp, cid, data) ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)]) chunk(fp, "IEND", "") try: fp.flush() except: pass
def _save(im, fp, filename): try: rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] except KeyError: raise IOError("cannot write mode %s as TIFF" % im.mode) ifd = ImageFileDirectory(prefix) # -- multi-page -- skip TIFF header on subsequent pages if fp.tell() == 0: # tiff header (write via IFD to get everything right) # PIL always starts the first IFD at offset 8 fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) ifd[IMAGEWIDTH] = im.size[0] ifd[IMAGELENGTH] = im.size[1] # additions written by Greg Couch, [email protected] # inspired by image-sig posting from Kevin Cazabon, [email protected] if hasattr(im, 'tag'): # preserve tags from original TIFF image file for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): if key in im.tag.tagdata: ifd[key] = im.tag.tagdata.get(key) # preserve some more tags from original TIFF image file # -- 2008-06-06 Florian Hoech ifd.tagtype = im.tag.tagtype for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP): if key in im.tag: ifd[key] = im.tag[key] # preserve ICC profile (should also work when saving other formats # which support profiles as TIFF) -- 2008-06-06 Florian Hoech if "icc_profile" in im.info: ifd[ICCPROFILE] = im.info["icc_profile"] if "description" in im.encoderinfo: ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] if "resolution" in im.encoderinfo: ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] = _cvt_res( im.encoderinfo["resolution"]) if "x resolution" in im.encoderinfo: ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) if "y resolution" in im.encoderinfo: ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) if "resolution unit" in im.encoderinfo: unit = im.encoderinfo["resolution unit"] if unit == "inch": ifd[RESOLUTION_UNIT] = 2 elif unit == "cm" or unit == "centimeter": ifd[RESOLUTION_UNIT] = 3 else: ifd[RESOLUTION_UNIT] = 1 if "software" in im.encoderinfo: ifd[SOFTWARE] = im.encoderinfo["software"] if "date time" in im.encoderinfo: ifd[DATE_TIME] = im.encoderinfo["date time"] if "artist" in im.encoderinfo: ifd[ARTIST] = im.encoderinfo["artist"] if "copyright" in im.encoderinfo: ifd[COPYRIGHT] = im.encoderinfo["copyright"] dpi = im.encoderinfo.get("dpi") if dpi: ifd[RESOLUTION_UNIT] = 2 ifd[X_RESOLUTION] = _cvt_res(dpi[0]) ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) if bits != (1, ): ifd[BITSPERSAMPLE] = bits if len(bits) != 1: ifd[SAMPLESPERPIXEL] = len(bits) if extra is not None: ifd[EXTRASAMPLES] = extra if format != 1: ifd[SAMPLEFORMAT] = format ifd[PHOTOMETRIC_INTERPRETATION] = photo if im.mode == "P": lut = im.im.getpalette("RGB", "RGB;L") ifd[COLORMAP] = tuple([ord(v) * 256 for v in lut]) # data orientation stride = len(bits) * ((im.size[0] * bits[0] + 7) // 8) ifd[ROWSPERSTRIP] = im.size[1] ifd[STRIPBYTECOUNTS] = stride * im.size[1] ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer ifd[COMPRESSION] = 1 # no compression offset = ifd.save(fp) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, offset, (rawmode, stride, 1))]) # -- helper for multi-page save -- if "_debug_multipage" in im.encoderinfo: #just to access o32 and o16 (using correct byte order) im._debug_multipage = ifd
def _save(im, fp, filename): if im.mode != "RGB": raise IOError("cannot write mode %s as WEBP" % im.mode) im.encoderconfig = (im.encoderinfo.get("quality", 0), ) ImageFile._save(im, fp, [("webp", (0, 0) + im.size, 0, (im.mode, ))])
def _save(im, fp, filename, check=0): if im.mode == "P": # we assume this is a color Palm image with the standard colormap, # unless the "info" dict has a "custom-colormap" field rawmode = "P" bpp = 8 version = 1 elif im.mode == "L" and im.encoderinfo.has_key( "bpp") and im.encoderinfo["bpp"] in (1, 2, 4): # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because # Palm does greyscale from white (0) to black (1) bpp = im.encoderinfo["bpp"] im = im.point(lambda x, shift=8 - bpp, maxval=(1 << bpp) - 1: maxval - (x >> shift)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4): # here we assume that even though the inherent mode is 8-bit grayscale, only # the lower bpp bits are significant. We invert them to match the Palm. bpp = im.info["bpp"] im = im.point(lambda x, maxval=(1 << bpp) - 1: maxval - (x & maxval)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "1": # monochrome -- write it inverted, as is the Palm standard rawmode = "1;I" bpp = 1 version = 0 else: raise IOError, "cannot write mode %s as Palm" % im.mode if check: return check # # make sure image data is available im.load() # write header cols = im.size[0] rows = im.size[1] rowbytes = ((cols + (16 / bpp - 1)) / (16 / bpp)) * 2 transparent_index = 0 compression_type = _COMPRESSION_TYPES["none"] flags = 0 if im.mode == "P" and im.info.has_key("custom-colormap"): flags = flags & _FLAGS["custom-colormap"] colormapsize = 4 * 256 + 2 colormapmode = im.palette.mode colormap = im.getdata().getpalette() else: colormapsize = 0 if im.info.has_key("offset"): offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4 else: offset = 0 fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) fp.write(chr(bpp)) fp.write(chr(version)) fp.write(o16b(offset)) fp.write(chr(transparent_index)) fp.write(chr(compression_type)) fp.write(o16b(0)) # reserved by Palm # now write colormap if necessary if colormapsize > 0: fp.write(o16b(256)) for i in range(256): fp.write(chr(i)) if colormapmode == 'RGB': fp.write( chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2])) elif colormapmode == 'RGBA': fp.write( chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2])) # now convert data to raw form ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))]) fp.flush()
def _save(im, fp, filename): # # make sure image data is available im.load() xref = [0]*(5+1) # placeholders fp.write("%PDF-1.2\n") fp.write("% created by PIL PDF driver " + __version__ + "\n") # # Get image characteristics width, height = im.size # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits) # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports # Flatedecode (zip compression). bits = 8 params = None if im.mode == "1": filter = "/ASCIIHexDecode" colorspace = "/DeviceGray" procset = "/ImageB" # grayscale bits = 1 elif im.mode == "L": filter = "/DCTDecode" # params = "<< /Predictor 15 /Columns %d >>" % (width-2) colorspace = "/DeviceGray" procset = "/ImageB" # grayscale elif im.mode == "P": filter = "/ASCIIHexDecode" colorspace = "[ /Indexed /DeviceRGB 255 <" palette = im.im.getpalette("RGB") for i in range(256): r = ord(palette[i*3]) g = ord(palette[i*3+1]) b = ord(palette[i*3+2]) colorspace = colorspace + "%02x%02x%02x " % (r, g, b) colorspace = colorspace + "> ]" procset = "/ImageI" # indexed color elif im.mode == "RGB": filter = "/DCTDecode" colorspace = "/DeviceRGB" procset = "/ImageC" # color images elif im.mode == "CMYK": filter = "/DCTDecode" colorspace = "/DeviceCMYK" procset = "/ImageC" # color images else: raise ValueError("cannot save mode %s" % im.mode) # # catalogue xref[1] = fp.tell() _obj(fp, 1, Type = "/Catalog", Pages = "2 0 R") _endobj(fp) # # pages xref[2] = fp.tell() _obj(fp, 2, Type = "/Pages", Count = 1, Kids = "[4 0 R]") _endobj(fp) # # image op = StringIO.StringIO() if filter == "/ASCIIHexDecode": if bits == 1: # FIXME: the hex encoder doesn't support packed 1-bit # images; do things the hard way... data = im.tostring("raw", "1") im = Image.new("L", (len(data), 1), None) im.putdata(data) ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)]) elif filter == "/DCTDecode": ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)]) elif filter == "/FlateDecode": ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)]) elif filter == "/RunLengthDecode": ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)]) else: raise ValueError("unsupported PDF filter (%s)" % filter) xref[3] = fp.tell() _obj(fp, 3, Type = "/XObject", Subtype = "/Image", Width = width, Height = height, Length = len(op.getvalue()), Filter = filter, BitsPerComponent = bits, DecodeParams = params, ColorSpace = colorspace) fp.write("stream\n") fp.write(op.getvalue()) fp.write("\nendstream\n") _endobj(fp) # # page xref[4] = fp.tell() _obj(fp, 4) fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\ "/Resources <<\n/ProcSet [ /PDF %s ]\n"\ "/XObject << /image 3 0 R >>\n>>\n"\ "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\ (procset, width, height)) _endobj(fp) # # page contents op = StringIO.StringIO() op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (width, height)) xref[5] = fp.tell() _obj(fp, 5, Length = len(op.getvalue())) fp.write("stream\n") fp.write(op.getvalue()) fp.write("\nendstream\n") _endobj(fp) # # trailer startxref = fp.tell() fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref)) for x in xref[1:]: fp.write("%010d 00000 n \n" % x) fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)) fp.write("startxref\n%d\n%%%%EOF\n" % startxref) fp.flush()
def _save(im, fp, filename): # # make sure image data is available im.load() xref = [0] * (5 + 1) # placeholders fp.write("%PDF-1.2\n") fp.write("% created by PIL PDF driver " + __version__ + "\n") # # Get image characteristics width, height = im.size # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits) # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports # Flatedecode (zip compression). params = None if im.mode == "1": filter = "/ASCIIHexDecode" config = "/DeviceGray", "/ImageB", 1 elif im.mode == "L": filter = "/DctDecode" # params = "<< /Predictor 15 /Columns %d >>" % (width-2) config = "/DeviceGray", "/ImageB", 8 elif im.mode == "P": filter = "/ASCIIHexDecode" config = "/Indexed", "/ImageI", 8 elif im.mode == "RGB": filter = "/DCTDecode" config = "/DeviceRGB", "/ImageC", 8 elif im.mode == "CMYK": filter = "/DCTDecode" config = "/DeviceRGB", "/ImageC", 8 else: raise ValueError, "illegal mode" colorspace, proc, bits = config # # catalogue xref[1] = fp.tell() _obj(fp, 1, Type="/Catalog", Pages="2 0 R") _endobj(fp) # # pages xref[2] = fp.tell() _obj(fp, 2, Type="/Pages", Count=1, Kids="[4 0 R]") _endobj(fp) # # image op = StringIO.StringIO() if filter == "/ASCIIHexDecode": ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, None)]) elif filter == "/DCTDecode": ImageFile._save(im, op, [("jpeg", (0, 0) + im.size, 0, im.mode)]) elif filter == "/FlateDecode": ImageFile._save(im, op, [("zip", (0, 0) + im.size, 0, im.mode)]) elif filter == "/RunLengthDecode": ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)]) else: raise ValueError, "unsupported PDF filter" xref[3] = fp.tell() _obj( fp, 3, Type="/XObject", Subtype="/Image", Width=width, Height=height, Length=len(op.getvalue()), Filter=filter, BitsPerComponent=bits, DecodeParams=params, ColorSpace=colorspace, ) fp.write("stream\n") fp.write(op.getvalue()) fp.write("\nendstream\n") _endobj(fp) # # page xref[4] = fp.tell() fp.write( "4 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n" "/Resources <<\n/ProcSet [ /PDF %s ]\n" "/XObject << /image 3 0 R >>\n>>\n" "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" % (proc, width, height) ) # # page contents op = StringIO.StringIO() op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (width, height)) xref[5] = fp.tell() _obj(fp, 5, Length=len(op.getvalue())) fp.write("stream\n") fp.write(op.getvalue()) _endobj(fp) # # trailer startxref = fp.tell() fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref)) for x in xref[1:]: fp.write("%010d 00000 n \n" % x) fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)) fp.write("startxref\n%d\n%%%%EOF\n" % startxref) fp.flush()
def _save(im, fp, filename): try: rawmode, photo, format, bits, extra = SAVE_INFO[im.mode] except KeyError: raise IOError("cannot write mode %s as TIFF" % im.mode) ifd = ImageFileDirectory() # tiff header (write via IFD to get everything right) fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) ifd[IMAGEWIDTH] = im.size[0] ifd[IMAGELENGTH] = im.size[1] # additions written by Greg Couch, [email protected] # inspired by image-sig posting from Kevin Cazabon, [email protected] if hasattr(im, 'tag'): # preserve tags from original TIFF image file for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): if key in im.tag.tagdata: ifd[key] = im.tag.tagdata.get(key) if "description" in im.encoderinfo: ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] if "resolution" in im.encoderinfo: ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \ = _cvt_res(im.encoderinfo["resolution"]) if "x resolution" in im.encoderinfo: ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) if "y resolution" in im.encoderinfo: ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) if "resolution unit" in im.encoderinfo: unit = im.encoderinfo["resolution unit"] if unit == "inch": ifd[RESOLUTION_UNIT] = 2 elif unit == "cm" or unit == "centimeter": ifd[RESOLUTION_UNIT] = 3 else: ifd[RESOLUTION_UNIT] = 1 if "software" in im.encoderinfo: ifd[SOFTWARE] = im.encoderinfo["software"] if "date time" in im.encoderinfo: ifd[DATE_TIME] = im.encoderinfo["date time"] if "artist" in im.encoderinfo: ifd[ARTIST] = im.encoderinfo["artist"] if "copyright" in im.encoderinfo: ifd[COPYRIGHT] = im.encoderinfo["copyright"] dpi = im.encoderinfo.get("dpi") if dpi: ifd[RESOLUTION_UNIT] = 1 ifd[X_RESOLUTION] = _cvt_res(dpi[0]) ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) if bits != (1,): ifd[BITSPERSAMPLE] = bits if len(bits) != 1: ifd[SAMPLESPERPIXEL] = len(bits) if extra is not None: ifd[EXTRASAMPLES] = extra if format != 1: ifd[SAMPLEFORMAT] = format ifd[PHOTOMETRIC_INTERPRETATION] = photo if im.mode == "P": lut = im.im.getpalette("RGB", "RGB;L") ifd[COLORMAP] = tuple([ord(v) * 256 for v in lut]) # data orientation stride = len(bits) * ((im.size[0]*bits[0]+7)//8) ifd[ROWSPERSTRIP] = im.size[1] ifd[STRIPBYTECOUNTS] = stride * im.size[1] ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer ifd[COMPRESSION] = 1 # no compression offset = ifd.save(fp) ImageFile._save(im, fp, [ ("raw", (0,0)+im.size, offset, (rawmode, stride, 1)) ])
def _save(im, fp, filename): # # make sure image data is available im.load() xref = [0] * (5 + 1) # placeholders fp.write("%PDF-1.2\n") fp.write("% created by PIL PDF driver " + __version__ + "\n") # # Get image characteristics width, height = im.size # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits) # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports # Flatedecode (zip compression). bits = 8 params = None if im.mode == "1": filter = "/ASCIIHexDecode" colorspace = "/DeviceGray" procset = "/ImageB" # grayscale bits = 1 elif im.mode == "L": filter = "/DCTDecode" # params = "<< /Predictor 15 /Columns %d >>" % (width-2) colorspace = "/DeviceGray" procset = "/ImageB" # grayscale elif im.mode == "P": filter = "/ASCIIHexDecode" colorspace = "[ /Indexed /DeviceRGB 255 <" palette = im.im.getpalette("RGB") for i in range(256): r = ord(palette[i * 3]) g = ord(palette[i * 3 + 1]) b = ord(palette[i * 3 + 2]) colorspace = colorspace + "%02x%02x%02x " % (r, g, b) colorspace = colorspace + "> ]" procset = "/ImageI" # indexed color elif im.mode == "RGB": filter = "/DCTDecode" colorspace = "/DeviceRGB" procset = "/ImageC" # color images elif im.mode == "CMYK": filter = "/DCTDecode" colorspace = "/DeviceCMYK" procset = "/ImageC" # color images else: raise ValueError("cannot save mode %s" % im.mode) # # catalogue xref[1] = fp.tell() _obj(fp, 1, Type="/Catalog", Pages="2 0 R") _endobj(fp) # # pages xref[2] = fp.tell() _obj(fp, 2, Type="/Pages", Count=1, Kids="[4 0 R]") _endobj(fp) # # image op = StringIO.StringIO() if filter == "/ASCIIHexDecode": if bits == 1: # FIXME: the hex encoder doesn't support packed 1-bit # images; do things the hard way... data = im.tostring("raw", "1") im = Image.new("L", (len(data), 1), None) im.putdata(data) ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)]) elif filter == "/DCTDecode": ImageFile._save(im, op, [("jpeg", (0, 0) + im.size, 0, im.mode)]) elif filter == "/FlateDecode": ImageFile._save(im, op, [("zip", (0, 0) + im.size, 0, im.mode)]) elif filter == "/RunLengthDecode": ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)]) else: raise ValueError("unsupported PDF filter (%s)" % filter) xref[3] = fp.tell() _obj(fp, 3, Type="/XObject", Subtype="/Image", Width=width, Height=height, Length=len(op.getvalue()), Filter=filter, BitsPerComponent=bits, DecodeParams=params, ColorSpace=colorspace) fp.write("stream\n") fp.write(op.getvalue()) fp.write("\nendstream\n") _endobj(fp) # # page xref[4] = fp.tell() _obj(fp, 4) fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\ "/Resources <<\n/ProcSet [ /PDF %s ]\n"\ "/XObject << /image 3 0 R >>\n>>\n"\ "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\ (procset, width, height)) _endobj(fp) # # page contents op = StringIO.StringIO() op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (width, height)) xref[5] = fp.tell() _obj(fp, 5, Length=len(op.getvalue())) fp.write("stream\n") fp.write(op.getvalue()) fp.write("\nendstream\n") _endobj(fp) # # trailer startxref = fp.tell() fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref)) for x in xref[1:]: fp.write("%010d 00000 n \n" % x) fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)) fp.write("startxref\n%d\n%%%%EOF\n" % startxref) fp.flush()
def _save(im, fp, filename): try: rawmode, byteorder, photo, format, bits, extra = SAVE_INFO[im.mode] except KeyError: raise IOError, "cannot write mode %s as TIFF" % im.mode ifd = ImageFileDirectory(BYTEORDER_TO_PREFIX[byteorder]) #seb -- multi-page -- added `if` if fp.tell() == 0: # tiff header (write via IFD to get everything right) # PIL always starts the first IFD at offset 8 fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) ifd[IMAGEWIDTH] = im.size[0] ifd[IMAGELENGTH] = im.size[1] # additions written by Greg Couch, [email protected] # inspired by image-sig posting from Kevin Cazabon, [email protected] if hasattr(im, 'tag'): # preserve tags from original TIFF image file for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): if im.tag.tagdata.has_key(key): ifd[key] = im.tag.tagdata.get(key) if im.encoderinfo.has_key("description"): ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] if im.encoderinfo.has_key("resolution"): ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \ = _cvt_res(im.encoderinfo["resolution"]) if im.encoderinfo.has_key("x resolution"): ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) if im.encoderinfo.has_key("y resolution"): ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) if im.encoderinfo.has_key("resolution unit"): unit = im.encoderinfo["resolution unit"] if unit == "inch": ifd[RESOLUTION_UNIT] = 2 elif unit == "cm" or unit == "centimeter": ifd[RESOLUTION_UNIT] = 3 else: ifd[RESOLUTION_UNIT] = 1 if im.encoderinfo.has_key("software"): ifd[SOFTWARE] = im.encoderinfo["software"] if im.encoderinfo.has_key("date time"): ifd[DATE_TIME] = im.encoderinfo["date time"] if im.encoderinfo.has_key("artist"): ifd[ARTIST] = im.encoderinfo["artist"] if im.encoderinfo.has_key("copyright"): ifd[COPYRIGHT] = im.encoderinfo["copyright"] dpi = im.encoderinfo.get("dpi") if dpi: ifd[RESOLUTION_UNIT] = 1 ifd[X_RESOLUTION] = _cvt_res(dpi[0]) ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) if bits != (1, ): ifd[BITSPERSAMPLE] = bits if len(bits) != 1: ifd[SAMPLESPERPIXEL] = len(bits) if extra is not None: ifd[EXTRASAMPLES] = extra if format != 1: ifd[SAMPLEFORMAT] = format ifd[PHOTOMETRIC_INTERPRETATION] = photo if im.mode == "P": lut = im.im.getpalette("RGB", "RGB;L") ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut)) # data orientation stride = len(bits) * ((im.size[0] * bits[0] + 7) // 8) #seb-// ifd[ROWSPERSTRIP] = im.size[1] ifd[STRIPBYTECOUNTS] = stride * im.size[1] ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer ifd[COMPRESSION] = 1 # no compression offset = ifd.save(fp) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, offset, (rawmode, stride, 1))]) #seb -- multi-page -- if im.encoderinfo.has_key("_debug_multipage"): #just to access o32 and o16 (using correct byte order) im._debug_multipage = ifd
def _save(im, fp, filename, chunk=putchunk, check=0): # save an image to disk (called by the save method) mode = im.mode if mode == "P": # # attempt to minimize storage requirements for palette images if im.encoderinfo.has_key("bits"): # number of bits specified by user n = 1 << im.encoderinfo["bits"] else: # check palette contents n = 256 # FIXME if n <= 2: bits = 1 elif n <= 4: bits = 2 elif n <= 16: bits = 4 else: bits = 8 if bits != 8: mode = "%s;%d" % (mode, bits) # encoder options if im.encoderinfo.has_key("dictionary"): dictionary = im.encoderinfo["dictionary"] else: dictionary = "" im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary) # get the corresponding PNG mode try: rawmode, mode = _OUTMODES[mode] except KeyError: raise IOError, "cannot write mode %s as PNG" % mode if check: return check # # write minimal PNG file fp.write(_MAGIC) chunk(fp, "IHDR", o32(im.size[0]), o32(im.size[1]), # 0: size mode, # 8: depth/type chr(0), # 10: compression chr(0), # 11: filter category chr(0)) # 12: interlace flag if im.mode == "P": chunk(fp, "PLTE", im.im.getpalette("RGB")) if im.encoderinfo.has_key("transparency"): if im.mode == "P": transparency = max(0, min(255, im.encoderinfo["transparency"])) chunk(fp, "tRNS", chr(255) * transparency + chr(0)) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, "tRNS", o16(transparency)) else: raise IOError, "cannot use transparency for this mode" if 0: # FIXME: to be supported some day chunk(fp, "gAMA", o32(int(gamma * 100000.0))) dpi = im.encoderinfo.get("dpi") if dpi: chunk(fp, "pHYs", o32(int(dpi[0] / 0.0254 + 0.5)), o32(int(dpi[1] / 0.0254 + 0.5)), chr(1)) info = im.encoderinfo.get("pnginfo") if info: for cid, data in info.chunks: chunk(fp, cid, data) ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)]) chunk(fp, "IEND", "") try: fp.flush() except: pass
def _save(im, fp, filename): try: rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] except KeyError: raise IOError, "cannot write mode %s as TIFF" % im.mode ifd = ImageFileDirectory(prefix) # -- multi-page -- skip TIFF header on subsequent pages if fp.tell() == 0: # tiff header (write via IFD to get everything right) # PIL always starts the first IFD at offset 8 fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) ifd[IMAGEWIDTH] = im.size[0] ifd[IMAGELENGTH] = im.size[1] # additions written by Greg Couch, [email protected] # inspired by image-sig posting from Kevin Cazabon, [email protected] if hasattr(im, 'tag'): # preserve tags from original TIFF image file for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): if im.tag.tagdata.has_key(key): ifd[key] = im.tag.tagdata.get(key) # preserve some more tags from original TIFF image file # -- 2008-06-06 Florian Hoech ifd.tagtype = im.tag.tagtype for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP): if im.tag.has_key(key): ifd[key] = im.tag[key] # preserve ICC profile (should also work when saving other formats # which support profiles as TIFF) -- 2008-06-06 Florian Hoech if im.info.has_key("icc_profile"): ifd[ICCPROFILE] = im.info["icc_profile"] if im.encoderinfo.has_key("description"): ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] if im.encoderinfo.has_key("resolution"): ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["resolution"]) if im.encoderinfo.has_key("x resolution"): ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) if im.encoderinfo.has_key("y resolution"): ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) if im.encoderinfo.has_key("resolution unit"): unit = im.encoderinfo["resolution unit"] if unit == "inch": ifd[RESOLUTION_UNIT] = 2 elif unit == "cm" or unit == "centimeter": ifd[RESOLUTION_UNIT] = 3 else: ifd[RESOLUTION_UNIT] = 1 if im.encoderinfo.has_key("software"): ifd[SOFTWARE] = im.encoderinfo["software"] if im.encoderinfo.has_key("date time"): ifd[DATE_TIME] = im.encoderinfo["date time"] if im.encoderinfo.has_key("artist"): ifd[ARTIST] = im.encoderinfo["artist"] if im.encoderinfo.has_key("copyright"): ifd[COPYRIGHT] = im.encoderinfo["copyright"] dpi = im.encoderinfo.get("dpi") if dpi: ifd[RESOLUTION_UNIT] = 2 ifd[X_RESOLUTION] = _cvt_res(dpi[0]) ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) if bits != (1,): ifd[BITSPERSAMPLE] = bits if len(bits) != 1: ifd[SAMPLESPERPIXEL] = len(bits) if extra is not None: ifd[EXTRASAMPLES] = extra if format != 1: ifd[SAMPLEFORMAT] = format ifd[PHOTOMETRIC_INTERPRETATION] = photo if im.mode == "P": lut = im.im.getpalette("RGB", "RGB;L") ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut)) # data orientation stride = len(bits) * ((im.size[0]*bits[0]+7)/8) ifd[ROWSPERSTRIP] = im.size[1] ifd[STRIPBYTECOUNTS] = stride * im.size[1] ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer ifd[COMPRESSION] = 1 # no compression offset = ifd.save(fp) ImageFile._save(im, fp, [ ("raw", (0,0)+im.size, offset, (rawmode, stride, 1)) ]) # -- helper for multi-page save -- if im.encoderinfo.has_key("_debug_multipage"): #just to access o32 and o16 (using correct byte order) im._debug_multipage = ifd
def _save(im, fp, filename): if _imaging_gif: # call external driver try: _imaging_gif.save(im, fp, filename) return except IOError: pass # write uncompressed file try: rawmode = RAWMODE[im.mode] imOut = im except KeyError: # convert on the fly (EXPERIMENTAL -- I'm not sure PIL # should automatically convert images on save...) if Image.getmodebase(im.mode) == "RGB": imOut = im.convert("P") rawmode = "P" else: imOut = im.convert("L") rawmode = "L" # header for s in getheader(imOut, im.encoderinfo): fp.write(s) flags = 0 try: interlace = im.encoderinfo["interlace"] except KeyError: interlace = 1 # workaround for @PIL153 if min(im.size) < 16: interlace = 0 if interlace: flags = flags | 64 try: transparency = im.encoderinfo["transparency"] except KeyError: pass else: # transparency extension block fp.write("!" + chr(249) + # extension intro chr(4) + # length chr(1) + # transparency info present o16(0) + # duration chr(int(transparency)) # transparency index + chr(0)) # local image header fp.write("," + o16(0) + o16(0) + # bounding box o16(im.size[0]) + # size o16(im.size[1]) + chr(flags) + # flags chr(8)) # bits imOut.encoderconfig = (8, interlace) ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)]) fp.write("\0") # end of image data fp.write(";") # end of file try: fp.flush() except: pass
def _save(im, fp, filename, check=0): if im.mode == 'RGB': # we assume that this is to be converted to the Palm 16-bit directcolor # format, which has 5 bits of red, 6 bits of green, and 5 bits of blue pixels = im.getdata() monochrome = 1 for p in pixels: if p != (255,255,255) and p != (0,0,0): monochrome = 0 break if monochrome: im = im.convert('1') rawmode = '1;I' bpp = 1 version = 1 else: newpixels = map(reduce_rgb, pixels) im = Image.new('I', im.size, 1) im.load() index = 0 for y in range(im.size[1]): for x in range(im.size[0]): im.putpixel((x,y), newpixels[index]) index = index + 1 rawmode = 'I;16B' bpp = 16 version = 2 elif im.mode == "P": # we assume this is a color Palm image with the standard colormap, # unless the "info" dict has a "custom-colormap" field # FIXME: Fails if 0 and 255 are remapped in a custom way. monochrome = 1 if im.info.has_key("custom-colormap"): monochrome = 0 else: for p in im.getdata(): c = _Palm8BitColormapValues[ p ]; if c != (255,255,255) and c != (0,0,0): monochrome = 0 break if monochrome: im = im.convert('1') rawmode = '1;I' bpp = 1 version = 1 else: rawmode = "P" bpp = 8 version = 1 elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4): # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because # Palm does greyscale from white (0) to black (1) monochrome = 1 for p in im.getdata(): if p != 0 and p != 255: monochrome = 0 break if monochrome: im = im.convert('1') rawmode = '1;I' bpp = 1 version = 1 else: bpp = im.encoderinfo["bpp"] im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4): # here we assume that even though the inherent mode is 8-bit grayscale, only # the lower bpp bits are significant. We invert them to match the Palm. maxval = (1 << bpp)-1 pixels = im.getdata() monochrome = 1 for p in pixels: if (p&maxval) != 0 and (p&maxval) != maxval: monochrome = 0 break if monochrome: im = Image.new('1', im.size, 1) im.load() index = 0 for y in range(im.size[1]): for x in range(im.size[0]): if ( pixels[index] == maxval ): value = 1 else: value = 0 im.putpixel((x,y), value) index = index + 1 rawmode = '1;I' bpp = 1 version = 1 else: bpp = im.info["bpp"] im = im.point(lambda x: maxval - (x & maxval)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "1": # monochrome -- write it inverted, as is the Palm standard rawmode = "1;I" bpp = 1 version = 0 else: raise IOError("cannot write mode %s as Palm" % im.mode) if check: return check # # make sure image data is available im.load() # write header cols = im.size[0] rows = im.size[1] rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2; transparent_index = 0 compression_type = _COMPRESSION_TYPES["none"] flags = 0; if im.mode == "P" and im.info.has_key("custom-colormap"): flags = flags | _FLAGS["custom-colormap"] colormapsize = 4 * 256 + 2; colormapmode = im.palette.mode colormap = im.getdata().getpalette() else: colormapsize = 0 if rawmode == 'I;16B': flags = flags | _FLAGS["directColor"] if im.info.has_key("offset"): offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4; else: offset = 0 fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) fp.write(chr(bpp)) fp.write(chr(version)) fp.write(o16b(offset)) fp.write(chr(transparent_index)) fp.write(chr(compression_type)) fp.write(o16b(0)) # reserved by Palm # now write colormap if necessary if colormapsize > 0: fp.write(o16b(256)) for i in range(256): fp.write(chr(i)) if colormapmode == 'RGB': fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2])) elif colormapmode == 'RGBA': fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2])) # if directColor, write out bpp info if rawmode == 'I;16B': fp.write(chr(5) + chr(6) + chr(5) + chr(0)) # now write out the transparent color fp.write(chr(0) + chr(0) + chr(0) + chr(0)) # now convert data to raw form ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))]) fp.flush()
def _save(im, fp, filename, chunk=putchunk, check=0): # save an image to disk (called by the save method) mode = im.mode if mode == "P": # # attempt to minimize storage requirements for palette images if im.encoderinfo.has_key("bits"): # number of bits specified by user n = 1 << im.encoderinfo["bits"] else: # check palette contents n = 256 # FIXME if n <= 2: bits = 1 elif n <= 4: bits = 2 elif n <= 16: bits = 4 else: bits = 8 if bits != 8: mode = "%s;%d" % (mode, bits) # encoder options if im.encoderinfo.has_key("dictionary"): dictionary = im.encoderinfo["dictionary"] else: dictionary = "" im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary) # get the corresponding PNG mode try: rawmode, mode = _OUTMODES[mode] except KeyError: raise IOError, "cannot write mode %s as PNG" % mode if check: return check # # write minimal PNG file fp.write(_MAGIC) chunk(fp, "IHDR", o32(im.size[0]), o32(im.size[1]), # 0: size mode, # 8: depth/type chr(0), # 10: compression chr(0), # 11: filter category chr(0)) # 12: interlace flag if im.mode == "P": chunk(fp, "PLTE", im.im.getpalette("RGB")) if im.encoderinfo.has_key("transparency"): if im.mode == "P": transparency = max(0, min(255, im.encoderinfo["transparency"])) chunk(fp, "tRNS", chr(255) * transparency + chr(0)) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, "tRNS", o16(transparency)) elif im.mode == "RGB": red, green, blue = im.encoderinfo["transparency"] chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue)) else: raise IOError("cannot use transparency for this mode") if 0: # FIXME: to be supported some day chunk(fp, "gAMA", o32(int(gamma * 100000.0))) dpi = im.encoderinfo.get("dpi") if dpi: chunk(fp, "pHYs", o32(int(dpi[0] / 0.0254 + 0.5)), o32(int(dpi[1] / 0.0254 + 0.5)), chr(1)) info = im.encoderinfo.get("pnginfo") if info: for cid, data in info.chunks: chunk(fp, cid, data) # ICC profile writing support -- 2008-06-06 Florian Hoech if im.info.has_key("icc_profile"): # ICC profile # according to PNG spec, the iCCP chunk contains: # Profile name 1-79 bytes (character string) # Null separator 1 byte (null character) # Compression method 1 byte (0) # Compressed profile n bytes (zlib with deflate compression) try: import ICCProfile p = ICCProfile.ICCProfile(im.info["icc_profile"]) name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79] except ImportError: name = "ICC Profile" data = name + "\0\0" + zlib.compress(im.info["icc_profile"]) chunk(fp, "iCCP", data) ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)]) chunk(fp, "IEND", "") try: fp.flush() except: pass
def _save(im, fp, filename): if _imaging_gif: # call external driver try: _imaging_gif.save(im, fp, filename) return except IOError: pass # write uncompressed file try: rawmode = RAWMODE[im.mode] imOut = im except KeyError: # convert on the fly (EXPERIMENTAL -- I'm not sure PIL # should automatically convert images on save...) if Image.getmodebase(im.mode) == "RGB": imOut = im.convert("P") rawmode = "P" else: imOut = im.convert("L") rawmode = "L" # header for s in getheader(imOut, im.encoderinfo): fp.write(s) flags = 0 try: interlace = im.encoderinfo["interlace"] except KeyError: interlace = 1 # workaround for @PIL153 if min(im.size) < 16: interlace = 0 if interlace: flags = flags | 64 try: transparency = im.encoderinfo["transparency"] except KeyError: pass else: # transparency extension block fp.write("!" + chr(249) + # extension intro chr(4) + # length chr(1) + # transparency info present o16(0) + # duration chr(int(transparency)) # transparency index + chr(0)) # local image header fp.write("," + o16(0) + o16(0) + # bounding box o16(im.size[0]) + # size o16(im.size[1]) + chr(flags) + # flags chr(8)) # bits imOut.encoderconfig = (8, interlace) ImageFile._save(imOut, fp, [("gif", (0, 0) + im.size, 0, rawmode)]) fp.write("\0") # end of image data fp.write(";") # end of file try: fp.flush() except: pass
def _save(im, fp, filename, check=0): if im.mode == "P": # we assume this is a color Palm image with the standard colormap, # unless the "info" dict has a "custom-colormap" field rawmode = "P" bpp = 8 version = 1 elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4): # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because # Palm does greyscale from white (0) to black (1) bpp = im.encoderinfo["bpp"] im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4): # here we assume that even though the inherent mode is 8-bit grayscale, only # the lower bpp bits are significant. We invert them to match the Palm. bpp = im.info["bpp"] im = im.point(lambda x, maxval=(1 << bpp)-1: maxval - (x & maxval)) # we ignore the palette here im.mode = "P" rawmode = "P;" + str(bpp) version = 1 elif im.mode == "1": # monochrome -- write it inverted, as is the Palm standard rawmode = "1;I" bpp = 1 version = 0 else: raise IOError, "cannot write mode %s as Palm" % im.mode if check: return check # # make sure image data is available im.load() # write header cols = im.size[0] rows = im.size[1] rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2; transparent_index = 0 compression_type = _COMPRESSION_TYPES["none"] flags = 0; if im.mode == "P" and im.info.has_key("custom-colormap"): flags = flags & _FLAGS["custom-colormap"] colormapsize = 4 * 256 + 2; colormapmode = im.palette.mode colormap = im.getdata().getpalette() else: colormapsize = 0 if im.info.has_key("offset"): offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4; else: offset = 0 fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) fp.write(chr(bpp)) fp.write(chr(version)) fp.write(o16b(offset)) fp.write(chr(transparent_index)) fp.write(chr(compression_type)) fp.write(o16b(0)) # reserved by Palm # now write colormap if necessary if colormapsize > 0: fp.write(o16b(256)) for i in range(256): fp.write(chr(i)) if colormapmode == 'RGB': fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2])) elif colormapmode == 'RGBA': fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2])) # now convert data to raw form ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))]) fp.flush()