2014-12-17 09:00:16 +01:00
#!/usr/bin/env python
2015-08-04 12:06:12 +02:00
'''
2015-09-26 18:01:28 +02:00
Run this script every time you change one of the png files . Using pngcrush , it will optimize the png files , remove various color profiles , remove ancillary chunks ( alla ) and text chunks ( text ) .
2015-08-04 12:06:12 +02:00
#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
'''
2014-12-17 09:00:16 +01:00
import os
import sys
import subprocess
2015-01-14 13:49:43 +01:00
import hashlib
from PIL import Image
def file_hash ( filename ) :
''' Return hash of raw file contents '''
with open ( filename , ' rb ' ) as f :
return hashlib . sha256 ( f . read ( ) ) . hexdigest ( )
def content_hash ( filename ) :
''' Return hash of RGBA contents of image '''
i = Image . open ( filename )
i = i . convert ( ' RGBA ' )
2015-09-26 18:01:28 +02:00
data = i . tobytes ( )
2015-01-14 13:49:43 +01:00
return hashlib . sha256 ( data ) . hexdigest ( )
2014-12-17 09:00:16 +01:00
2015-01-14 13:49:43 +01:00
pngcrush = ' pngcrush '
git = ' git '
2017-10-17 18:41:28 +02:00
folders = [ " src/qt/res/movies " , " src/qt/res/icons " , " src/qt/res/icons/crownium " , " src/qt/res/icons/drkblue " , " src/qt/res/icons/light " , " src/qt/res/icons/trad " , " src/qt/res/images " , " src/qt/res/images/crownium " , " src/qt/res/images/drkblue " , " src/qt/res/images/light " , " src/qt/res/images/trad " , " share/pixmaps " ]
2015-01-14 13:49:43 +01:00
basePath = subprocess . check_output ( [ git , ' rev-parse ' , ' --show-toplevel ' ] ) . rstrip ( ' \n ' )
2014-12-17 09:00:16 +01:00
totalSaveBytes = 0
2015-08-04 12:06:12 +02:00
noHashChange = True
2014-12-17 09:00:16 +01:00
outputArray = [ ]
for folder in folders :
absFolder = os . path . join ( basePath , folder )
for file in os . listdir ( absFolder ) :
extension = os . path . splitext ( file ) [ 1 ]
if extension . lower ( ) == ' .png ' :
print ( " optimizing " + file + " ... " ) ,
file_path = os . path . join ( absFolder , file )
2015-01-14 13:49:43 +01:00
fileMetaMap = { ' file ' : file , ' osize ' : os . path . getsize ( file_path ) , ' sha256Old ' : file_hash ( file_path ) } ;
fileMetaMap [ ' contentHashPre ' ] = content_hash ( file_path )
2014-12-17 09:00:16 +01:00
pngCrushOutput = " "
try :
2015-01-14 13:49:43 +01:00
pngCrushOutput = subprocess . check_output (
[ pngcrush , " -brute " , " -ow " , " -rem " , " gAMA " , " -rem " , " cHRM " , " -rem " , " iCCP " , " -rem " , " sRGB " , " -rem " , " alla " , " -rem " , " text " , file_path ] ,
stderr = subprocess . STDOUT ) . rstrip ( ' \n ' )
2014-12-17 09:00:16 +01:00
except :
print " pngcrush is not installed, aborting... "
sys . exit ( 0 )
#verify
2015-01-14 13:49:43 +01:00
if " Not a PNG file " in subprocess . check_output ( [ pngcrush , " -n " , " -v " , file_path ] , stderr = subprocess . STDOUT ) :
2014-12-17 09:00:16 +01:00
print " PNG file " + file + " is corrupted after crushing, check out pngcursh version "
sys . exit ( 1 )
2015-01-14 13:49:43 +01:00
fileMetaMap [ ' sha256New ' ] = file_hash ( file_path )
fileMetaMap [ ' contentHashPost ' ] = content_hash ( file_path )
if fileMetaMap [ ' contentHashPre ' ] != fileMetaMap [ ' contentHashPost ' ] :
print " Image contents of PNG file " + file + " before and after crushing don ' t match "
sys . exit ( 1 )
2014-12-17 09:00:16 +01:00
fileMetaMap [ ' psize ' ] = os . path . getsize ( file_path )
outputArray . append ( fileMetaMap )
print ( " done \n " ) ,
print " summary: \n +++++++++++++++++ "
for fileDict in outputArray :
2015-01-14 13:49:43 +01:00
oldHash = fileDict [ ' sha256Old ' ]
newHash = fileDict [ ' sha256New ' ]
2014-12-17 09:00:16 +01:00
totalSaveBytes + = fileDict [ ' osize ' ] - fileDict [ ' psize ' ]
2015-08-04 12:06:12 +02:00
noHashChange = noHashChange and ( oldHash == newHash )
2014-12-17 09:00:16 +01:00
print fileDict [ ' file ' ] + " \n size diff from: " + str ( fileDict [ ' osize ' ] ) + " to: " + str ( fileDict [ ' psize ' ] ) + " \n old sha256: " + oldHash + " \n new sha256: " + newHash + " \n "
2015-08-04 12:06:12 +02:00
print " completed. Checksum stable: " + str ( noHashChange ) + " . Total reduction: " + str ( totalSaveBytes ) + " bytes "