Created
May 21, 2015 13:16
-
-
Save GrantTrebbin/4aba7898840d96fc6b86 to your computer and use it in GitHub Desktop.
Compressing Similar PNG Images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from PIL import Image | |
import numpy | |
import argparse | |
import os | |
import sys | |
#Configure argument parser to take input arguments | |
parser = argparse.ArgumentParser(description='Compress similar PNG images') | |
parser.add_argument('firstFile', type=argparse.FileType('r'), | |
help='First Image File') | |
parser.add_argument('secondFile', type=argparse.FileType('r'), | |
help='Second Image File') | |
args = parser.parse_args() | |
#Open first image | |
firstImageObject = Image.open(args.firstFile.name) | |
firstImMode = firstImageObject.mode | |
#Convert first image to array | |
if (firstImMode == 'L'): | |
print ('L') | |
firstImage = numpy.asarray(firstImageObject) | |
firstImageChannels = 1 | |
elif (firstImMode == 'P'): | |
print ('p') | |
firstImage = numpy.asarray(firstImageObject.convert('RGBA')) | |
firstImageChannels = 4 | |
elif (firstImMode == 'RGB'): | |
print ('rgb') | |
firstImage = numpy.asarray(firstImageObject) | |
firstImageChannels = 3 | |
elif (firstImMode == 'RGBA'): | |
print ('rgba') | |
firstImage = numpy.asarray(firstImageObject) | |
firstImageChannels = 4 | |
else: | |
sys.exit("This type of image can't be handled, maybe it is palette based") | |
#Open second image | |
secondImageObject = Image.open(args.secondFile.name) | |
secondImMode = secondImageObject.mode | |
#Convert second image to array | |
if (secondImMode == 'L'): | |
secondImage = numpy.asarray(secondImageObject) | |
secondImageChannels = 1 | |
elif (secondImMode == 'P'): | |
secondImage = numpy.asarray(secondImageObject.convert('RGBA')) | |
secondImageChannels = 4 | |
elif (secondImMode == 'RGB'): | |
secondImage = numpy.asarray(secondImageObject) | |
secondImageChannels = 3 | |
elif (secondImMode == 'RGBA'): | |
secondImage = numpy.asarray(secondImageObject) | |
secondImageChannels = 4 | |
else: | |
sys.exit("This type of image can't be handled, maybe it is palette based") | |
#Check to make sure the images have the same number of channels | |
if (firstImageChannels != secondImageChannels): | |
sys.exit("The two images have a different number of channels") | |
#Check to make sure the images are the same size | |
if (firstImage.shape != secondImage.shape) : | |
sys.exit("Image dimensions don't match") | |
#calculate difference and sign images | |
differenceImage = numpy.subtract(firstImage.astype('int'), secondImage.astype('int')) | |
absoluteDifferenceImage = numpy.abs(differenceImage) | |
imageSign = 255*(differenceImage < 0).astype('uint8') | |
#Write sign and difference images to file for each channel | |
for channel in range(0,firstImageChannels): | |
if (firstImageChannels == 1): | |
imOut = Image.fromarray(absoluteDifferenceImage.astype('uint8')) | |
signOut = Image.fromarray(imageSign.astype('uint8')) | |
else: | |
imOut = Image.fromarray(absoluteDifferenceImage[:,:,channel].astype('uint8')) | |
signOut = Image.fromarray(imageSign[:,:,channel].astype('uint8')) | |
imOut.save(args.firstFile.name + args.secondFile.name + str(channel) + "D.png") | |
signOut.save(args.firstFile.name + args.secondFile.name + str(channel) + "S.png") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from PIL import Image | |
import numpy | |
import argparse | |
import os | |
import sys | |
#Configure argument parser to take input arguments | |
parser = argparse.ArgumentParser(description='Expand compressed PNG images. Example ' + | |
'"imInflate.py 1.png 2.png" takes the ' + | |
'file 1.png and uses the files ' + | |
'1.png2.pngxD.png and 1.png2.pngxS.png ' + | |
'to recreate 2.png Two images are required ' + | |
'for each channel of the first file, where x ' + | |
'in the above example is the channel number ') | |
parser.add_argument('baseFileName', help='Base Image File') | |
parser.add_argument('outputFileName', help='Output Image File') | |
args = parser.parse_args() | |
#Load base Image | |
with Image.open(args.baseFileName) as baseImageObject: | |
baseImMode = baseImageObject.mode | |
if (baseImMode == 'L'): | |
baseImage = numpy.asarray(baseImageObject) | |
baseImageChannels = 1 | |
elif (baseImMode == 'P'): | |
baseImage = numpy.asarray(baseImageObject.convert('RGBA')) | |
baseImageChannels = 4 | |
elif (baseImMode == 'RGB'): | |
baseImage = numpy.asarray(baseImageObject) | |
baseImageChannels = 3 | |
elif (baseImMode == 'RGBA'): | |
baseImage = numpy.asarray(baseImageObject) | |
baseImageChannels = 4 | |
else: | |
sys.exit("This type of image can't be handled, maybe it is palette based") | |
#Make base image writeable | |
baseImage.setflags(write=True) | |
print (baseImageChannels) | |
for channel in range(0,baseImageChannels): | |
with Image.open(args.baseFileName + args.outputFileName + str(channel) + "D" + ".png") as diffFile: | |
absoluteDifferenceImage = numpy.asarray(diffFile) | |
with Image.open(args.baseFileName + args.outputFileName + str(channel) + "S" + ".png") as signFile: | |
signImage = numpy.asarray(signFile) | |
signMask = (-2*(signImage)//255 + 1) | |
differenceImage = numpy.multiply(absoluteDifferenceImage, signMask) | |
if (baseImageChannels == 1): | |
baseImage = baseImage - differenceImage | |
print (numpy.min(baseImage)) | |
else: | |
baseImage[:,:,channel] = baseImage[:,:,channel] - differenceImage | |
imOut = Image.fromarray(baseImage.astype('uint8')) | |
imOut.save(args.outputFileName) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment