def fig_save(self, **kwargs): import datetime from PIL import Image, PngImagePlugin metadata = { "Creator": "Lia Hankla", "Description": "Simulation: " + self.config + "_" + self.specs, "Creation Time": datetime.datetime.now().isoformat() } if "fig_type" not in kwargs: fig_type = "scratch/" else: fig_type = kwargs["fig_type"] if "fig_name" not in kwargs: tit = plt.gca().get_title() tit = tit.replace(' ', '-') fig_name = tit + ".png" else: fig_name = kwargs["fig_name"] fig_dir = self.fig_save_fp + fig_type + "/" if not os.path.exists(fig_dir): os.makedirs(fig_dir) fig_name = fig_dir + fig_name try: plt.savefig(fig_name, bbox_inches='tight') # insert metadata after the fact img = Image.open(fig_name) meta = PngImagePlugin.PngInfo() for k, v in metadata.items(): meta.add_text(k, v) img.save(fig_name, "png", pnginfo=meta) except: print("Could not save figure " + fig_name) else: print("saving figure " + fig_name)
def to_raster(tmpfn, now): """ Convert the raw data into a RASTER Image 5 inch rain per hour is ~ 125 mm/hr, so over 5min that is 10 mm Index 255 is missing 0 is zero 1 is 0.1 mm 254 is 25.4 mm """ data = np.loadtxt(tmpfn, skiprows=10) # mm/hr to mm/5min imgdata = data * 10.0 / 12.0 imgdata = np.where(imgdata < 0, 255, imgdata) png = Image.fromarray(np.uint8(imgdata)) png.putpalette(mrms.make_colorramp()) meta = PngImagePlugin.PngInfo() meta.add_text("title", now.strftime("%Y%m%d%H%M"), 0) png.save("%s.png" % (tmpfn, ), pnginfo=meta) del png # Make worldfile with open("%s.wld" % (tmpfn, ), "w") as fh: fh.write("""0.004167 0.00 0.00 -0.004167 44.53785 -89.89942""")
def to_png(self): if self.leftoffset != None: from PIL import PngImagePlugin import zlib def _crc32(data, seed=0): return zlib.crc32(data, seed) & 0xffffffff with io.BytesIO() as png: pnginfo = PngImagePlugin.PngInfo() # There is a bug in PngImagePlugin, it can't just write arbitrary chunk names, just particular ones in a couple lists. # https://pillow.readthedocs.io/en/stable/_modules/PIL/PngImagePlugin.html#PngInfo # Look near 'info = im.encoderinfo.get("pnginfo")' # So add a 'valid' chunk name. 'iTXt' is nice because it can be added multiple times. Then replace its name in the output. grab_data = struct.pack('>ii', self.leftoffset, self.topoffset) pnginfo.add(b'iTXt', grab_data) # TODO: Support 'alPh'? self.save(png, format='PNG', pnginfo=pnginfo) png_bytes = png.getvalue() png_bytes = png_bytes.replace( b'iTXt' + grab_data + struct.pack('>I', _crc32(grab_data, _crc32(b'iTXt'))), b'grAb' + grab_data + struct.pack('>I', _crc32(grab_data, _crc32(b'grAb'))), 1) return png_bytes else: with io.BytesIO() as png: self.save(png, format='PNG') png_bytes = png.getvalue() return png_bytes
def _raw_canvas(self): # Create the sprite canvas width, height = self.sprite.canvas_size canvas = PILImage.new('RGBA', (width, height), (0, 0, 0, 0)) # Paste the images inside the canvas for image in self.sprite.images: canvas.paste( image.image, (round_up(image.x + (image.padding[3] + image.margin[3]) * self.sprite.max_ratio), round_up(image.y + (image.padding[0] + image.margin[0]) * self.sprite.max_ratio))) meta = PngImagePlugin.PngInfo() meta.add_text('Software', 'glue-%s' % __version__) meta.add_text('Comment', self.sprite.hash) # Customize how the png is going to be saved kwargs = dict(optimize=False, pnginfo=meta) if self.sprite.config['png8']: # Get the alpha band alpha = canvas.split()[-1] canvas = canvas.convert('RGB').convert('P', palette=PILImage.ADAPTIVE, colors=255) # Set all pixel values below 128 to 255, and the rest to 0 mask = PILImage.eval(alpha, lambda a: 255 if a <= 128 else 0) # Paste the color of index 255 and use alpha as a mask canvas.paste(255, mask) kwargs.update({'transparency': 255}) return canvas, kwargs
def screenshot(self, e=None): ts = time.strftime("%Y %b %d %H-%M-%S", time.gmtime()) i = PngImagePlugin.PngInfo() i.add_text("pos", " ".join([str(round(x, 3)) for x in self.pos])) i.add_text("dir", " ".join([str(round(x, 3)) for x in self.vv])) self.cframe.save(PATH + "Screenshots/Screenshot " + ts + ".png", pnginfo=i)
def createimagethumb(fpath, el): md5 = eencode(fpath) infile = os.path.basename(fpath) uuri = "file://" + urllib.parse.quote( fpath, safe='/', encoding=None, errors=None) fmtime = int(os.path.getmtime(fpath)) try: # img = el.picture_to_img(fpath) if img.mode == "P": img = img.convert("RGBA") try: bimg = ImageOps.expand(img, border=1, fill=BORDER_COLOR) except: bimg = img try: meta = PngImagePlugin.PngInfo() meta.add_text("Thumb URI", uuri, 0) meta.add_text("Thumb MTime", str(int(fmtime)), 0) meta.add_text("Software", "PYTHON::PIL", 0) bimg.save(XDG_CACHE_LARGE + md5 + ".png", "PNG", pnginfo=meta) img.close() return md5 except: return "Null" except: return "Null"
def _pngmeta(self): """Return GeoImage.tags as a PNG metadata object. Inspired by: public domain, Nick Galbreath http://blog.modp.com/2007/08/python-pil-and-png-metadata-take-2.html """ reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect') try: tags = self.tags except AttributeError: tags = {} # Undocumented class from PIL import PngImagePlugin meta = PngImagePlugin.PngInfo() # Copy from tags to new dict for k__, v__ in tags.items(): if k__ not in reserved: meta.add_text(k__, v__, 0) return meta
def get_freedesktop_pnginfo(filename, image=None, thumb_info=None): """Gets png metadata for the thumbnail. :param filename: image filename :type filename: string :returns: png info :rtype: PngImagePlugin.PngInfo """ full_info = THUMB_INFO.copy() if thumb_info: full_info.update(thumb_info) file_stat = os.stat(filename) info = PngImagePlugin.PngInfo() info.add_text('Thumb::URI', get_uri(filename)) info.add_text('Thumb::MTime', str(get_mtime(filename, file_stat))) info.add_text('Thumb::Size', str(get_filesize(filename, file_stat))) if 'software' in full_info: info.add_text('Thumb::Software', full_info['software']) if 'height' in full_info: info.add_text('Thumb::Image::Height', str(full_info['height'])) elif image: info.add_text('Thumb::Image::Height', str(image.size[1])) if 'width' in full_info: info.add_text('Thumb::Image::Width', str(full_info['width'])) elif image: info.add_text('Thumb::Image::Width', str(image.size[0])) return info
def test_dos_total_memory(self): im = Image.new('L', (1, 1)) compressed_data = zlib.compress(b'a'*1024*1023) info = PngImagePlugin.PngInfo() for x in range(64): info.add_text('t%s' % x, compressed_data, zip=True) info.add_itxt('i%s' % x, compressed_data, zip=True) b = BytesIO() im.save(b, 'PNG', pnginfo=info) b.seek(0) try: im2 = Image.open(b) except ValueError as msg: self.assertIn("Too much memory", msg) return total_len = 0 for txt in im2.text.values(): total_len += len(txt) self.assertLess(total_len, 64*1024*1024, "Total text chunks greater than 64M")
def append_myself(params): """ Append some tags to PNG image """ title = 'PyArtForms ' + params['name'] p1 = copy.deepcopy(params) del p1['im'] del p1['call'] sp = str(p1) x = PngImagePlugin.PngInfo() today = dt.today() sdt = dt.now().strftime('%Y-%m-%d %H:%M:%S') y = today.year x.add_text(key='Title', value=title, zip=False) x.add_text(key='Description', value='generated in PyArtForms @' + sdt + '\r\n' + sp, zip=False) x.add_text(key='Author', value='Jakub Noniewicz aka MoNsTeR/GDC', zip=False) x.add_text(key='Copyright', value='(c)' + str(y) + ' Jakub Noniewicz | noniewicz.com | noniewicz.art.pl', zip=False) x.add_itxt( key='Concept', value= 'PyArtForms concept by: Jakub Noniewicz | noniewicz.com | noniewicz.art.pl', lang='', tkey='', zip=False) x.add_text(key='Software', value='PyArtForms', zip=False) return x
def set_png_metadata(self, png_filename, metadata): """ Takes a PNG filename and overwrites the fields specified in metadata with the values given, adding any new fields. """ im = Image.open(png_filename) # This hack works-around PIL's broken png metadata support. Disovered here: # http://blog.client9.com/2007/08/python-pil-and-png-metadata-take-2.html meta = PngImagePlugin.PngInfo() # These meta-data entries are added (eroneously) by PIL, ignore them reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect') # Add in the new metadata img_metadata = im.info.copy() img_metadata.update(metadata) # Add to the PNG for k, v in img_metadata.iteritems(): if k not in reserved: meta.add_text(k, v) # Write it out im.save(png_filename, pnginfo=meta)
def save_image_to_png(j, img, cm, target_dir): pitch = get_y_angle(cm.pose) roll = get_x_angle(cm.pose) meta = PngImagePlugin.PngInfo() meta.add_text("pitch", str(pitch)) meta.add_text("roll", str(roll)) img.save(target_dir + "/" + str(j) + ".png", pnginfo=meta)
def add_meta(fid, METADATA): # fid is string with path # METADATA is a dictionary with format field : value import os fid = os.path.realpath(fid) ext = fid.split('.')[-1] if ext == "png": """ PIL viene en el paquete Pillow """ from PIL import Image from PIL import PngImagePlugin im = Image.open(fid) meta = PngImagePlugin.PngInfo() for x in METADATA: meta.add_text(x, METADATA[x]) im.save(fid, "png", pnginfo=meta) elif ext == "svg": with open(fid, 'a') as im: im.write("\n<!-- \n") for x in METADATA: im.write(x + ' : ' + METADATA[x] + '\n') im.write("-->") else: print("Extension not recognized!")
def savefig_png(self, fn, *args, **kwargs): # This is a hack to deal with filenames without extensions. Not sure why # this is necessary. fn = os.path.splitext(fn)[0] + ".png" # We'll start by saving the figure because the metadata is going to be # inserted after the fact. ret = mpl_savefig(self, fn, *args, **kwargs) # If PIL isn't installed, we'll just call the standard savefig. if Image is None: logging.warn("PIL must be installed to add metadata to PNG files.") return ret # Get the git commit information. git_info = get_git_info() if git_info is None: return ret # Inject the git info into the figure as metadata. img = Image.open(fn) meta = PngImagePlugin.PngInfo() for k, v in git_info.items(): meta.add_text(k, v) img.save(fn, "png", pnginfo=meta) return ret
def add_image_metadata(f, metadata=None): # I don't know of a way using matplotlib, but you can add metadata to png's with PIL: im = Image.open(f) meta = PngImagePlugin.PngInfo() for key, value in metadata.items(): meta.add_text(key, value) im.save(f, "png", pnginfo=meta)
def test_nonunicode_text(self): # Check so that non-Unicode text is saved as a tEXt rather than iTXt im = Image.new("RGB", (32, 32)) info = PngImagePlugin.PngInfo() info.add_text("Text", "Ascii") im = roundtrip(im, pnginfo=info) self.assertIsInstance(im.info["Text"], str)
def polish(filename, w, h, hash="", viewhash=""): print(" Polishing...") img = Image.open(filename) img = img.convert("RGBA") pixdata = img.load() # Read top left pixel color - not robust to zoomed in images # tlc = pixdata[0,0] # init clipping bounds x1 = img.size[0] x2 = 0 y1 = img.size[1] y2 = 0 # Set background to white and transparent for y in xrange(img.size[1]): solidx = 0 solidy = 0 for x in xrange(img.size[0]): if pixdata[x, y] == bkc: pixdata[x, y] = (255, 255, 255, 0) else: if solidx == 0 and x < x1: x1 = x if solidy == 0 and y < y1: y1 = y solidx = x solidy = y if solidx > x2: x2 = solidx if solidy > y2: y2 = solidy x2 += 2 y2 += 2 # downsample (half the res) img = img.resize((w, h), Image.ANTIALIAS) # crop if (x1 < x2 and y1 < y2): img = img.crop((x1/2,y1/2,x2/2,y2/2)) # add hash to meta data meta = PngImagePlugin.PngInfo() # copy metadata into new object #for k,v in im.info.iteritems(): # if k in reserved: continue meta.add_text("csghash", hash, 0) meta.add_text("viewhash", viewhash, 0) # Save it img.save(filename, "PNG", pnginfo=meta) img.close()
def save_png(img, newname, headers): mantenha_variavel_name(newname) # print(type(headers)) # print("\n\n- HEADERS -") # print(type(headers)) # for keys, values in headers.items(): # print(str(keys)) # print(str(values) + "\n") # print("- END HEADERS -\n\n") try: binning = int(headers['Binning']) binning += 1 except Exception as e: print("Binning Type Error ->" + str(e)) binning = " ??? " newname_png = newname + ".png" img_png = img print("Opening filename") try: print("Tricat of save_png") imgarray = numpy.asarray(img_png, dtype=numpy.int32) info = PngImagePlugin.PngInfo() day_hour = get_date_hour_image_for_headers(str(headers['Start Time'])) try: info.add_text('Binning: ', str(binning) + "x" + str(binning)) info.add_text('CCD SET TEMP: ', str(headers['Set Temperature']) + u"\u00b0C") info.add_text('CCD Temperature: ', str(headers['Temperature']) + u"\u00b0C") info.add_text('CCD Type: ', str(headers['Imager ID'])) info.add_text('Exposure: ', str(headers['Exposure']) + "0 ms") info.add_text('Filter Label: ', str(headers['Filter Label'])) info.add_text('Filter Position: ', str(headers['Filter Position'])) info.add_text('Filter Wavelength: ', str(headers['Filter Wavelength'])) info.add_text('Filter Wheel Temperature: ', "25" + u"\u00b0C") info.add_text('Image Type: ', 'PNG') info.add_text('Latitude: ', str(headers['Latitude']) + u"\u00b0") info.add_text('Longitude: ', str(headers['Longitude']) + u"\u00b0") info.add_text('Moon Elevation: ', str(headers['Moon Elevation']) + u"\u00b0") info.add_text('Moon Phase: ', str(headers['Moon Phase']) + " %") info.add_text('Shutter CCD: ', str(headers['Open or close shutter'])) info.add_text('Shutter Lenz: ', str(headers['Open or close shutter'])) info.add_text('Site ID: ', str(headers['Observatory'])) info.add_text('Start Time: ', str(day_hour) + " UTC") info.add_text('Sun Elevation:', str(headers['Sun Elevation']) + u"\u00b0") info.add_text('Version: ', str(software_version)) except Exception as e: print("info.add_text: " + e) image = Image.fromarray(imgarray) image.save(newname_png, "PNG", pnginfo=info) # set_headers_png(newname_png) except Exception as e: print("Exception save_png -> {}".format(e))
def write_metadata_pil(file, metadata): """Enrich the file metadata with `metadata` dict thanks to PIL.""" from PIL import Image, PngImagePlugin im = Image.open(file) meta = PngImagePlugin.PngInfo() for k, v in metadata.items(): meta.add_text(k, v, 0) im.save(file, "PNG", pnginfo=meta) return True
def bake_obi_image(self, request=None): """Bake the OBI JSON badge award assertion into a copy of the original badge's image, if one exists.""" if request: base_url = request.build_absolute_uri('/') else: base_url = 'http://%s' % (Site.objects.get_current().domain, ) if self.badge.image: # Make a duplicate of the badge image self.badge.image.open() img_copy_fh = StringIO(self.badge.image.file.read()) else: # Make a copy of the default badge image img_copy_fh = StringIO(open(DEFAULT_BADGE_IMAGE, 'rb').read()) try: # Try processing the image copy, bail if the image is bad. img = Image.open(img_copy_fh) except IOError: return False # Here's where the baking gets done. JSON representation of the OBI # assertion gets written into the "openbadges" metadata field # see: http://blog.client9.com/2007/08/python-pil-and-png-metadata-take-2.html # see: https://github.com/mozilla/openbadges/blob/development/lib/baker.js # see: https://github.com/mozilla/openbadges/blob/development/controllers/baker.js try: from PIL import PngImagePlugin except ImportError: import PngImagePlugin meta = PngImagePlugin.PngInfo() # TODO: Will need this, if we stop doing hosted assertions # assertion = self.as_obi_assertion(request) # meta.add_text('openbadges', json.dumps(assertion)) hosted_assertion_url = '%s%s' % (base_url, reverse( 'badger.award_detail_json', args=(self.badge.slug, self.id))) meta.add_text('openbadges', hosted_assertion_url) # And, finally save out the baked image. new_img = StringIO() img.save(new_img, "PNG", pnginfo=meta) img_data = new_img.getvalue() name_before = self.image.name self.image.save('', ContentFile(img_data), False) if (self.image.storage.exists(name_before)): self.image.storage.delete(name_before) # Update the image field with the new image name # NOTE: Can't do a full save(), because this gets called in save() Award.objects.filter(pk=self.pk).update(image=self.image) return True
def write_meta(self, title, description): title, description = map(SanitationUtils.coerce_ascii, (title, description)) # print "title, description: ", title, ', ', description if self.is_png: # print "image is PNG" try: new = Image.open(os.path.join(self.dir, self.fname)) except Exception as exc: raise Exception('unable to open image: ' + str(exc)) meta = PngImagePlugin.PngInfo() meta.add_text("title", title) meta.add_text("description", description) try: new.save(os.path.join(self.dir, self.fname), pnginfo=meta) except Exception as exc: raise Exception('unable to write image: ' + str(exc)) elif self.is_jpg: # print "image is JPG" fullname = os.path.join(self.dir, self.fname) try: img = Image.open(fullname) except IOError: raise Exception("file not found: " + fullname) # write exif exif_dict = dict() if 'exif' in img.info: exif_dict = piexif.load(img.info["exif"]) if '0th' not in exif_dict: exif_dict['0th'] = {} exif_dict['0th'][piexif.ImageIFD.DocumentName] = title exif_dict['0th'][piexif.ImageIFD.ImageDescription] = description exif_bytes = piexif.dump(exif_dict) img.save(fullname, "jpeg", exif=exif_bytes) # write IPTC # for index, value in ( # ('Exif.Image.DocumentName', title), # ('Exif.Image.ImageDescription', description), # ('Iptc.Application2.Headline', title), # ('Iptc.Application2.Caption', description), # ): # # print " -> imgmeta[%s] : %s" % (index, value) # if index[:4] == 'Iptc' : # # print " --> setting IPTC key", index, "to", value # imgmeta[index] = [value] # if index[:4] == 'Exif' : # # print " --> setting EXIF key", index, "to", value # imgmeta[index] = value # imgmeta.write() else: raise Exception("not an image file: ", self.ext)
def __O0000OOOO000OOOOO(O00OOOO0OO0OO00O0): OO00000OO0OOO0O0O = QtWidgets.QFileDialog.getSaveFileName( O00OOOO0OO0OO00O0, 'Select Image to Save', 'deepnude.png', 'PNG Image (*.png)') metadata = PngImagePlugin.PngInfo() metadata.add_text('crusr', getpreferences('email')) O00OOOO0OO0OO00O0._Transform__O0O0OO00O0OOOOO0O.save( (OO00000OO0OOO0O0O[0]), 'PNG', pnginfo=metadata) O00OOOO0OO0OO00O0.back_signal.emit()
def convertRGBToPNG8(tile: Image, tilePath:str): info = PngImagePlugin.PngInfo() info.add_text("generated_by", "generatePyramid") tile = tile.convert('P', palette=Image.ADAPTIVE, colors=256) tmp_path = tilePath + '_bak.png' #tmp file on the same filesystem tile.save(tmp_path, quality=95, pnginfo=info) #now do an atomic move, which should work as we are on the same file system os.rename(tmp_path,tilePath)
def write_metadata(self, file, metadata): from PIL import Image, PngImagePlugin # FIXME: Detect and handle other file types (currently, the only user # is the thumbnails plugin, which generates PNG images). im = Image.open(file) meta = PngImagePlugin.PngInfo() for k, v in metadata.items(): meta.add_text(k, v, 0) im.save(file, "PNG", pnginfo=meta)
def write_image(self, im, fout): """ Write the image `im` to the path or file object `fout`. """ # PNG info mojo from: http://blog.modp.com/2007/08/python-pil-and-png-metadata-take-2.html from PIL import PngImagePlugin aptst = AptusState(self) info = PngImagePlugin.PngInfo() info.add_text("Software", "Aptus %s" % __version__) info.add_text("Aptus State", aptst.write_string()) info.add_text("Aptus Stats", json.dumps(self.stats)) im.save(fout, 'PNG', pnginfo=info)
def test_roundtrip_text(self): # Check text roundtripping with Image.open(TEST_PNG_FILE) as im: info = PngImagePlugin.PngInfo() info.add_text("TXT", "VALUE") info.add_text("ZIP", "VALUE", zip=True) im = roundtrip(im, pnginfo=info) assert im.info == {"TXT": "VALUE", "ZIP": "VALUE"} assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
def test_roundtrip_text(self): # Check text roundtripping im = Image.open(TEST_PNG_FILE) info = PngImagePlugin.PngInfo() info.add_text("TXT", "VALUE") info.add_text("ZIP", "VALUE", zip=True) im = roundtrip(im, pnginfo=info) self.assertEqual(im.info, {"TXT": "VALUE", "ZIP": "VALUE"}) self.assertEqual(im.text, {"TXT": "VALUE", "ZIP": "VALUE"})
def save_png(self, filename): """Save the ImageFile with metadata in a png file.""" pngname = os.path.splitext(filename)[0] + '.png' meta = PngImagePlugin.PngInfo() info = self.metadata.export_all() info = [(i.split('=')[0], "=".join(i.split('=')[1:])) for i in info] for k, v in info: meta.add_text(k, v) s = (self.image - self.image.min()) * 256 / (self.image.max() - self.image.min()) im = Image.fromarray(s.astype('uint8'), mode='L') im.save(pngname, pnginfo=meta)
def test_roundtrip_text(): # Check text roundtripping im = Image.open(file) info = PngImagePlugin.PngInfo() info.add_text("TXT", "VALUE") info.add_text("ZIP", "VALUE", 1) im = roundtrip(im, pnginfo=info) assert_equal(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'}) assert_equal(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
def save_png_with_metadata(fig, filename, fig_kwds, kwds): """ Save a matplotlib figure to a png with metadata """ from PIL import Image, PngImagePlugin fig.savefig(filename, **fig_kwds) im = Image.open(filename) meta = PngImagePlugin.PngInfo() for key in kwds: meta.add_text(str(key), str(kwds[key])) im.save(filename, "png", pnginfo=meta)