plupload, preserve_headers = false, and autorotation issue - exif

I have a jpeg image where the EXIF Orientation flag = 6, or "Rotate 90 CW". Here's the pertinent data from exiftool:
---- ExifTool ----
ExifTool Version Number : 12.44
---- File ----
File Name : orig.jpg
Image Width : 4032
Image Height : 3024
---- EXIF ----
Orientation : Rotate 90 CW
Exif Image Width : 4032
Exif Image Height : 3024
---- Composite ----
Image Size : 4032x3024
Here's how IrfanView presents the image, with auto-rotate turned off:
Using the plupload "Getting Started" script from here, with preserve_headers = false, I get an image without EXIF headers - as expected - but rotated 180 degrees, which is unexpected. Again, the view with IrfanView:
Here's the "resize" snippet from the code:
resize: {
width: 5000,
height: 5000,
preserve_headers: false
}
Is there something I'm doing wrong? I would have expected a 90 CW rotation on upload with the EXIF stripped.
Dan
Edit: I'm using plupload V2.3.9
BUMP
I'm getting the exact same result with plupload using these exif samples on github. I chose landscape_6, because it's Orientation is the same as my example ("Rotate 90 CW", or Orientation tag value 6). Here's the before and after upload views using IrfanView with no autorotate, preserve_headers = false:
Aren't these canonical examples for demonstrating exif properties? Unless I'm missing some fundamental point, plupload is busted. I'd much rather it be the former, and someone can tell me the error of my ways.

Related

Python converting images in TIF format to PNG

I am running the code below to convert files from tifs to PNGs but the converted images isn't converting properly the new files are disrupted and with lines in half of the file as can be seen in the attached image. Any idea why would this happen please?.
import os
from PIL import Image
yourpath = os.getcwd()
for root, dirs, files in os.walk(yourpath, topdown=False):
for name in files:
print(os.path.join(root, name))
if os.path.splitext(os.path.join(root, name))[1].lower() == ".tif":
if os.path.isfile(os.path.splitext(os.path.join(root, name))[0] + ".png"):
print ("A png file already exists for %s" % name)
# If a PNG is *NOT* present, create one from the tiff.
else:
outfile = os.path.splitext(os.path.join(root, name))[0] + ".png"
try:
im = Image.open(os.path.join(root, name))
print("Generating jpeg for %s" % name)
im.thumbnail(im.size)
im.save(outfile, "png", quality=100)
except Exception as e:
print (e)
Running tiffinfo gives the following details:
TIFF Directory at offset 0x8 (8)
Image Width: 1024 Image Length: 1024
Resolution: 5000, 5000 pixels/cm
Bits/Sample: 8
Sample Format: unsigned integer
Compression Scheme: LZW
Photometric Interpretation: RGB color
Samples/Pixel: 3
Rows/Strip: 1
Planar Configuration: separate image planes
ImageDescription: <?xml version="1.0" encoding="UTF-8"?><!-- Warning: this comment is an OME-XML metadata block, which contains crucial dimensional parameters and other important metadata. Please edit cautiously (if at all), and back up the original data before doing so. For more information, see the OME-TIFF web site: https://docs.openmicroscopy.org/latest/ome-model/ome-tiff/. --><OME xmlns="http://www.openmicroscopy.org/Schemas/OME/2016-06" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Creator="OME Bio-Formats 5.9.2" UUID="urn:uuid:5d7dfdcc-e0e9-4899-9aa2-64717b405232" xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2016-06 http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd"><Image ID="Image:0" Name="p1_Bromophenol_1mM - Mark_and_Find 001/Position026 (RGB rendering)"><Pixels BigEndian="true" DimensionOrder="XYCZT" ID="Pixels:0" PhysicalSizeX="2.0" PhysicalSizeXUnit="┬Ám" PhysicalSizeY="2.0" PhysicalSizeYUnit="┬Ám" PhysicalSizeZ="1.0" PhysicalSizeZUnit="┬Ám" SizeC="3" SizeT="1" SizeX="1024" SizeY="1024" SizeZ="1" TimeIncrement="1.0" TimeIncrementUnit="s" Type="uint8"><Channel ID="Channel:0:0" Name="red" SamplesPerPixel="3"><LightPath/></Channel><TiffData FirstC="0" FirstT="0" FirstZ="0" IFD="0" PlaneCount="1"><UUID FileName="Position026 (RGB rendering) - 1024 x 1024 x 1 x 1 - 3 ch (8 bits).tif">urn:uuid:5d7dfdcc-e0e9-4899-9aa2-64717b405232</UUID></TiffData></Pixels></Image></OME>
Software: OME Bio-Formats 5.9.2

Pillow : return a NoneType when extracting EXIF ​metadata

I tried to extract Exif metadata from a picture with Pillow.
When I import my picture on GIMP or XnView, the software returns to me Exif metadata :
EXIF metadata on GIMP
However, when I run my Python script like this :
from PIL import Image
from PIL.ExifTags import TAGS
def get_exif():
i = Image.open('./Datatest_img/DAFANCH96_023MIC07633_L.jpg')
info = i._getexif()
return {TAGS.get(tag): value for tag, value in info.items()}
print(get_exif())
the script returns to me an error as if the image did not contain EXIF ​​metadata :
Traceback (most recent call last):
File "test_exif.py", line 17, in <module>
print(get_exif())
File "test_exif.py", line 15, in get_exif
return {TAGS.get(tag): value for tag, value in info.items()}
AttributeError: 'NoneType' object has no attribute 'items'
I also tried printing .info in my script the code return :
{None: (200, 200)}
and I running exiftool in command Line, the terminal print :
$ exiftool DAFANCH96_023MIC07633_L.jpg
ExifTool Version Number : 11.99
File Name : DAFANCH96_023MIC07633_L.jpg
Directory : .
File Size : 791 kB
File Modification Date/Time : 2020:05:27 22:46:56+02:00
File Access Date/Time : 2020:05:28 10:54:31+02:00
File Inode Change Date/Time : 2020:05:27 22:46:57+02:00
File Permissions : rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : inches
X Resolution : 200
Y Resolution : 200
Image Width : 4096
Image Height : 2944
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 1
Image Size : 4096x2944
Megapixels : 12.1
Anyone have an idea ? Does anyone know what's going on ? thanks.

Aspect ration of a image for instagram

i want to change the aspect ratio of an image for the instagram with python .here is my code for change the aspact ration :
width,height=imageFile.size
aspectRatio = width/height
if(aspectRatio>=0.80 and aspectRatio<=1.90):
print("yeah")
else:
if(height>width):
futureHeight = width/.85
print(str(width)+" ,"+str(futureHeight))
print(width/futureHeight)
left = 0
int(futureHeight)
teetet = height-futureHeight/2
top = teetet / 4
right = width
bottom = height -150
im1 = imageFile.crop((left, top, right, bottom))
print(im1.size)
im1.show()
im1.save(image)
but still it show
ValueError: Incompatible aspect ratio.
whenever i try to upload this image
i resolved that using basic dimensions. using the inspector i saw that instagram convert images to 598.02x598.02 in the home page, so i typed:
im=PIL.Image.open(path)
im=im.resize((598,598), Image.ANTIALIAS)
im.save(path) # overwrite the image
instead of
im=PIL.Image.open(path)
baseheight = 560
hpercent = (baseheight / float(im.size[1]))
wsize = int((float(im.size[0]) * float(hpercent)))
im=im.resize((wsize, baseheight), PIL.Image.ANTIALIAS)
im.save(path)
in wich aspect ratio is out of range anyway.
now you can post it using something like instabot without troubles 'cause the aspect ratio is 1.0 .

what type of array is being returned by tiff.imread()?

I am trying to get the RGB value of pixels from the TIFF image. So, what I did is:
import tifffile as tiff
a = tiff.imread("a.tif")
print (a.shape) #returns (1295, 1364, 4)
print(a) #returns [[[205 269 172 264]...[230 357 304 515]][[206 270 174 270] ... [140 208 183 286]]]
But since we know pixel color ranges from (0,255) for RGB. So, I don't understand what are these array returning, as some values are bigger than 255 and why are there 4 values?
By the way array size is 1295*1364 i.e size of image.
The normal reasons for a TIFF (or any other image) to be 4-bands are that it is:
RGBA, i.e. it contains Red, Green and Blue channels plus an alpha/transparency channel, or
CMYK, i.e. it contains Cyan, Magenta, Yellow and Black channels - this is most common in the print industry where "separations" are used in 4-colour printing, see here, or
that it is multi-band imagery, such as satellite images with Red, Green, Blue and Near Infra-red bands, e.g. Landsat MSS (Multi Spectral Scanner) or somesuch.
Note that some folks use TIFF files for topographic information, bathymetric information, microscopy and other purposes.
The likely reason for the values to be greater than 256, is that it is 16-bit data. Though it could be 10-bit, 12-bit, 32-bit, floats, doubles or something else.
Without access to your image, it is not possible to say much more. With access to your image, you could use ImageMagick at the command-line to find out more:
magick identify -verbose YourImage.TIF
Sample Output
Image: YourImage.TIF
Format: TIFF (Tagged Image File Format)
Mime type: image/tiff
Class: DirectClass
Geometry: 1024x768+0+0
Units: PixelsPerInch
Colorspace: CMYK <--- check this field
Type: ColorSeparation <--- ... and this one
Endianess: LSB
Depth: 16-bit
Channel depth:
Cyan: 16-bit <--- ... and this
Magenta: 1-bit <--- ... this
Yellow: 16-bit <--- ... and this
Black: 16-bit
Channel statistics:
...
...
You can scale the values like this:
from tifffile import imread
import numpy as np
# Open image
img = imread('image.tif')
# Convert to numpy array
npimg = np.array(img,dtype=np.float)
npimg[:,:,0]/=256
npimg[:,:,1]/=256
npimg[:,:,2]/=256
npimg[:,:,3]/=65535
print(np.mean(npimg[:,:,0]))
print(np.mean(npimg[:,:,1]))
print(np.mean(npimg[:,:,2]))
print(np.mean(npimg[:,:,3]))

Image Processing: Merging images with PIL.paste

i have a 2 list of png images, list _c and list _v. I want to paste _v on _c using a code like:
from PIL import Image
background = [Image.open(path, 'r') for path in glob.glob(list_c_path)]
foreground = [Image.open(path, 'r') for path in glob.glob(list_v_path)]
for im in range(len(background)):
pasted = background[im].paste(foreground[im], (0, 0), foreground[im])
This code won't work but it will give you and idea of what i want. I also need to have the images read in grayscale format before they are pasted.
Here's a sample of a background image:
Here's a sample of a foreground image:
And this is the desired result:
I pasted this images using this code:
background = Image.open('1000_c.png')
foreground = Image.open('1000_v.png')
background.paste(foreground, (0, 0), foreground)
background.save('example.png')
How can i achieve this??
Thanks in advance
Mmmm... your result images are identical to your foreground images because although the foreground images have an alpha/transparency layer, they are fully opaque and completely conceal your backgrounds. You need to have a rethink!
You can use ImageMagick in the Terminal to inspect your images. So, let's look at your foreground image:
identify -verbose fg.png
Sample Output
Image: fg.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: DirectClass
Geometry: 118x128+0+0
Units: Undefined
Colorspace: sRGB
Type: PaletteAlpha <--- Image does have alpha/transparency layer
Base type: Undefined
Endianess: Undefined
Depth: 8-bit
Channel depth:
Red: 8-bit
Green: 8-bit
Blue: 8-bit
Alpha: 1-bit
Channel statistics:
Pixels: 15104
Red:
min: 30 (0.117647)
...
...
Alpha:
min: 255 (1) <--- ... but alpha layer is fully opaque
max: 255 (1)
mean: 255 (1)
standard deviation: 0 (0)
kurtosis: 8.192e+51
skewness: 1e+36
entropy: 0
So there is no point pasting a fully opaque image over a background as it will fully conceal it.
If we punch a transparent hole in your foreground image with ImageMagick:
convert fg.png -region 100x100+9+14 -alpha transparent fg.png
It now looks like this:
And if we then run your code:
#!/usr/local/bin/python3
from PIL import Image
background = Image.open('bg.png')
foreground = Image.open('fg.png')
background.paste(foreground, (0, 0), foreground)
background.save('result.png')
It works:
So the moral of the story is that your foreground image either needs some transparency to allow the background to show through, or you need to use some blending mode to choose one or the other of the foreground and background images at each location, or to choose some combination - e.g. the average of the two, or the brighter of the two.
If you want to average the two images, or in fact, do any other blending mode, you could consider using Pillow's ImageChops module - documentation here. So, an average would look like this:
#!/usr/local/bin/python3
from PIL import Image, ImageChops
bg = Image.open('bg.png')
fg = Image.open('fg.png')
# Average the two images, i.e. add and divide by 2
result = ImageChops.add(bg, fg, scale=2.0)
result.save('result.png')

Resources