Resizing A 48bit Png Retaining Its 48bits, Without Dropping It To A 24bit File
Solution 1:
You can use imageio
with freeimage
library using format='PNG-FI'
in imageio.imread
/ imageoio.imwrite
.
Based on information in source code of freeimage.py in imageio
to install freeimage
library you can use imageio
:
in command line (on Linux it works even without full path)
imageio_download_bin freeimage
using python code
import imageio imageio.plugins.freeimage.download()
Probably if you install library (.dll
/.so
) directly from FreeImage webpage then it will also work.
Image has to be copied (img.copy()
). Because making image smaller it removed pixels with the biggest values so I work with part of image and make its bigger.
# read 48bit color
img = imageio.imread("..\\..\\000000_10.png", format='PNG-FI')
# max values in imageprint('shape:', img.shape)
print('max R:', img[:,:,0].max())
print('max G:', img[:,:,1].max())
print('max B:', img[:,:,2].max())
print('---')
# cut-off part of image (with)
img = img.copy()
img = img[370:375,1020:1025,:]
img = img.copy()
img.resize((256,256,3))
print('shape:', img.shape)
print('max R:', img[:,:,0].max())
print('max G:', img[:,:,1].max())
print('max B:', img[:,:,2].max())
print('---')
# find X,Y for first max red valueprint('max X:', img[:,:,0].max(axis=0).argmax())
print('max Y:', img[:,:,0].max(axis=1).argmax())
print(' flat:', img[:,:,0].argmax())
print('---')
# find X,Y for all max red values
max_r = img[:,:,0].max()
for y, row inenumerate(img[:,:,0]):
for x, it inenumerate(row):
if it == max_r:
print('value/x/y:', max_r, x, y)
# write 48bit color
imageio.imwrite('output_48bit.png', img, format='PNG-FI')
Output:
shape:(375,1242,3)max R:40827max G:36674max B:1---shape:(256,256,3)max R:40827max G:36506max B:1---max X:14max Y:0flat:14---value/x/y:40827140
In Linux I can use program `file in command line to check if file use 48bit color (16bits per color)
$file000000_10.png000000_10.png:PNGimagedata,1242 x375,16-bit/colorRGB,non-interlaced$fileoutput_48bit.pngoutput_48bit.png:PNGimagedata,256x256,16-bit/colorRGB,non-interlaced
If you have RGBA
then it will use 64bit color.
Example from imageio
issues: Unable to properly read multi-channel 16-bit png files
import imageio
import numpy as np
img_out = np.zeros((256, 256, 4), dtype=np.uint16)
color_grad = np.reshape(np.arange(2**16), (256,-1))
img_out[:, :, 0] = color_grad
img_out[:, :, 1] = np.rot90(color_grad, 1)
img_out[:, :, 2] = np.rot90(color_grad, 2)
img_out[:, :, 3] = np.rot90(color_grad, 3)
print('Write unique values: R={}, G={}, B={}, A={}'.format(
len(set(img_out[:, :, 0].flatten().tolist())),
len(set(img_out[:, :, 1].flatten().tolist())),
len(set(img_out[:, :, 2].flatten().tolist())),
len(set(img_out[:, :, 3].flatten().tolist()))))
imageio.imwrite('64bit_imageio.png', img_out, format='PNG-FI')
img_in_imageio = imageio.imread('64bit_imageio.png', format='PNG-FI')
print('imageio PNG unique values: R={}, G={}, B={}, A={}'.format(
len(set(img_in_imageio[:, :, 0].flatten().tolist())),
len(set(img_in_imageio[:, :, 1].flatten().tolist())),
len(set(img_in_imageio[:, :, 2].flatten().tolist())),
len(set(img_in_imageio[:, :, 3].flatten().tolist()))))
Output:
Write uniquevalues: R=65536, G=65536, B=65536, A=65536
imageio PNG uniquevalues: R=65536, G=65536, B=65536, A=65536
output_48bit.png: PNG image data, 5 x 5, 16-bit/color RGB, non-interlaced
EDIT: Your last code with more readable names for variables (lower_case_names) and few free lines to make it also more readable.
In original code you had mess so finally you wrote original image instead of resized one.
import cv2
import imageio
# need it only once #imageio.plugins.freeimage.download()
input_filename = "..\\..\\000000_10.png"
output_filename = "..\\..\\000000_10_resized.png"
input_image = imageio.imread(input_filename, format='PNG-FI')
output_image = cv2.resize(input_image, (256, 256))
imageio.imwrite(output_filename, output_image, format='PNG-FI')
Solution 2:
# Resize 48bit PNG file and maintain 48bit PNG when saving to file WORKINGimport cv2
import imageio
imageio.plugins.freeimage.download()
PNG_Location_Filepath = "..\\..\\000000_10.png"
Resized_Location_Filepath = "..\\..\\000000_10_resized.png"
img_in_imageio = imageio.imread(PNG_Location_Filepath, format='PNG-FI')
Resized_Image = cv2.resize(img_in_imageio, (256,256))
Saved_Filename = Resized_Location_Filepath
imageio.imwrite(Saved_Filename, Resized_Image, format='PNG-FI')
#This works to resize the image, keeping 48bits
Post a Comment for "Resizing A 48bit Png Retaining Its 48bits, Without Dropping It To A 24bit File"