I am trying to fix the corrupt exif warnings from tiff images and here's a code I am using
from PIL import Image
def remove_exif(image_name):
image = Image.open(image_name)
if not image.getexif():
return
print('removing EXIF from', image_name, '...')
data = list(image.getdata())
image_without_exif = Image.new(image.mode, image.size)
image_without_exif.putdata(data)
image_without_exif.save(image_name)
remove_exif('ggg.tiff')
print('Done')
The code is working and removed the exif but I got one page only while the tiff before the exif remove was of two pages.
Is it possible to keep all the pages of the tiff image?
I would like to convert an image obtained from the Windows Clipboard to PNG format without having to save and then reload.
As per the code below, I am saving the clipboard image and then reloading it.
Is there a way to convert the image to PNG format without those extra steps, such that the
PIL.BmpImagePlugin.DibImageFile gets converted to
PIL.PngImagePlugin.PngImageFile
Here is the current code:
from PIL import ImageGrab, Image
# Get the clipboard image
img1 = ImageGrab.grabclipboard()
# Save the image from the clipboard to file
img1.save('paste.png', 'PNG')
print("Image Type1:", type(img1))
# Load the image back in
img2 = Image.open('paste.png')
print("Image Type2:", type(img2))
OUTPUT:
Image Type1: <class 'PIL.BmpImagePlugin.DibImageFile'>
Image Type2: <class 'PIL.PngImagePlugin.PngImageFile'>
As per some help from Seon's comment, this got me on the right track, and fulfilled my requirements.
As per Seon:
"the idea is to save the image to an in-memory BytesIO object, and reload it from there. We're still saving and loading, but not to disk."
Which is exactly what I wanted.
Here is the code I used:
from PIL import ImageGrab, Image
import io
def convertImageFormat(imgObj, outputFormat="PNG"):
newImgObj = imgObj
if outputFormat and (imgObj.format != outputFormat):
imageBytesIO = io.BytesIO()
imgObj.save(imageBytesIO, outputFormat)
newImgObj = Image.open(imageBytesIO)
return newImgObj
# Get the clipboard image and convert to PNG
img1 = ImageGrab.grabclipboard()
img2 = convertImageFormat(img1)
# Check the types
print("Image Type1:", type(img1))
print("Image Type2:", type(img2))
OUTPUT:
Image Type1: <class 'PIL.BmpImagePlugin.DibImageFile'>
Image Type2: <class 'PIL.PngImagePlugin.PngImageFile'>
I'm working on a project where I receive a stream of JPEG images over WiFi, convert them to a bytearray, save them as PNG images and read them. The PIL.UnidentifiedImageError occurs when I attempt to open an saved PNG image.
This is how I save the bytearray of JPEG images into PNG images:
idx = random.randint(0,300)
image = Image.open(io.BytesIO(imgdata))
image.save(os.getcwd() + '/Frames/%d.png' % idx)
This is how I open the saved PNG images:
for file in os.listdir('/home/bitcraze/Desktop/AIdeck_examples/NINA/Frames/.'):
print (file)
if file.endswith(".png"):
full_file_path = '/home/Desktop/Frames/' + file
img_file = Image.open(full_file_path)
I checked other posts related to PIL.UnidentifiedImageError and it seems like it could be because the image is corrupted. The picture below shows how I receive the JPEG images:
EDIT: someone suggested I should include how I show the image.
img_loader = GdkPixbuf.PixbufLoader()
img_loader.write(imgdata)
img_loader.close()
pix = img_loader.get_pixbuf()
GLib.idle_add(self._update_image, pix)
I'm trying to convert heic file in jpeg importing also all metadadata (like gps info and other stuff), unfurtunately with the code below the conversion is ok but no metadata are stored on the jpeg file created.
Anyone can describe me what I need to add in the conversion method?
heif_file = pyheif.read("/transito/126APPLE_IMG_6272.HEIC")
image = Image.frombytes(
heif_file.mode,
heif_file.size,
heif_file.data,
"raw",
heif_file.mode,
heif_file.stride,
)
image.save("/transito/126APPLE_IMG_6272.JPEG", "JPEG")
Thanks, i found a solution, I hope can help others:
# Open the file
heif_file = pyheif.read(file_path_heic)
# Creation of image
image = Image.frombytes(
heif_file.mode,
heif_file.size,
heif_file.data,
"raw",
heif_file.mode,
heif_file.stride,
)
# Retrive the metadata
for metadata in heif_file.metadata or []:
if metadata['type'] == 'Exif':
exif_dict = piexif.load(metadata['data'])
# PIL rotates the image according to exif info, so it's necessary to remove the orientation tag otherwise the image will be rotated again (1° time from PIL, 2° from viewer).
exif_dict['0th'][274] = 0
exif_bytes = piexif.dump(exif_dict)
image.save(file_path_jpeg, "JPEG", exif=exif_bytes)
HEIF to JPEG:
from PIL import Image
import pillow_heif
if __name__ == "__main__":
pillow_heif.register_heif_opener()
img = Image.open("any_image.heic")
img.save("output.jpeg")
JPEG to HEIF:
from PIL import Image
import pillow_heif
if __name__ == "__main__":
pillow_heif.register_heif_opener()
img = Image.open("any_image.jpg")
img.save("output.heic")
Rotation (EXIF of XMP) will be removed automatically when needed.
Call to register_heif_opener can be replaced by importing pillow_heif.HeifImagePlugin instead of pillow_heif
Metadata can be edited in Pillow's "info" dictionary and will be saved when saving to HEIF.
Here is an other approach to convert iPhone HEIC images to JPG preserving exif data
Pyhton 3.9 (I'm on Rasperry PI 4 64 bit)
install pillow_heif (0.8.0)
And run following code and you'll find exif data in the new JPEG image.
The trick is to get the dictionary information. No additional conversion required.
This is sample code, built your own wrapper around.
from PIL import Image
import pillow_heif
# open the image file
heif_file = pillow_heif.read_heif("/mnt/pictures/test/IMG_0001.HEIC")
#create the new image
image = Image.frombytes(
heif_file.mode,
heif_file.size,
heif_file.data,
"raw",
heif_file.mode,
heif_file.stride,
)
print(heif_file.info.keys())
dictionary=heif_file.info
exif_dict=dictionary['exif']
# debug
print(exif_dict)
image.save('/tmp/test000.JPG', "JPEG", exif=exif_dict)
The object list_of_contents[0] is based64. I am trying to convert it to it's original image.
image_64_decode = base64.b64decode(list_of_contents[0])
image_result = open('test.jpg', 'wb')
image_result.write(image_64_decode)
img = Image.open(r'C:\Users\st-am\CANCER_APP\test.jpg')
However, I get the following error:
PIL.UnidentifiedImageError: cannot identify image file 'C:\\Users\\st-am\\CANCER_APP\\test.jpg'
Anybody has an idea why PIL cannot identify the image?
Here is the image