Skip to content

Instantly share code, notes, and snippets.

@DiverOfDark
Created October 30, 2023 10:02
Show Gist options
  • Save DiverOfDark/bdcb5fddb2499d465f2a312d2f03a585 to your computer and use it in GitHub Desktop.
Save DiverOfDark/bdcb5fddb2499d465f2a312d2f03a585 to your computer and use it in GitHub Desktop.
naive python gif crop
from os import listdir
from os.path import splitext, isfile, join
import gif
def optimizeImage(source_file):
target_file = source_file.replace("data", "data2")
file = open(source_file, 'rb')
file2 = open(target_file, 'wb')
reader = gif.Reader()
writer = gif.Writer(file2)
writer.write_header()
reader.feed(file.read())
if reader.has_screen_descriptor():
writer.write_screen_descriptor(reader.width, reader.height, has_color_table=len(reader.color_table) > 0,
depth=reader.original_depth)
writer.write_color_table(reader.color_table, reader.original_depth)
print('Processing %s' % source_file)
isFirst = 1
for block in reader.blocks:
if isinstance(block, gif.Image):
if isFirst:
isFirst = 0
writer.write_image(block.width, block.height, reader.original_depth, block.get_pixels(),
block.left,
block.top,
block.color_table, block.interlace, block.color_table_sorted)
else:
new_left_offset, new_top_offset, new_height, new_width, pixels = trimBlock(block, reader)
writer.write_image(new_width, new_height, reader.original_depth, pixels,
new_left_offset,
new_top_offset,
block.color_table, block.interlace, block.color_table_sorted)
elif isinstance(block, gif.NetscapeExtension):
writer.write_netscape_extension(block.loop_count, block.buffer_size or 0)
elif isinstance(block, gif.XMPDataExtension):
pass # writer.write_xmp_data_extension(block.get_metadata())
elif isinstance(block, gif.GraphicControlExtension):
writer.write_graphic_control_extension(block.disposal_method, block.delay_time, block.user_input,
block.has_transparent, block.transparent_color)
elif isinstance(block, gif.Trailer):
writer.write_trailer()
else:
raise "Fail"
if reader.has_unknown_block():
print('Encountered unknown block')
elif not reader.is_complete():
print('Missing trailer')
else:
print('Not a valid GIF file')
file.close()
file2.close()
def trimBlock(block, reader):
pixels = block.get_pixels()
len_pixels = len(pixels)
two_dimensional_array = [pixels[i:i + block.width] for i in range(0, len(pixels), block.width)]
left, lower, right, upper = findBoundaries(block, reader, two_dimensional_array)
new_left_offset, new_top_offset, new_height, new_width, trimmed_array = trimPixels(block, left, right, upper, lower,
two_dimensional_array)
pixels = [pixel for row in trimmed_array for pixel in row]
print("from %i x %i to %i x %i, pixels %i to %i" % (
block.width, block.height, new_width, new_height, len_pixels, len(pixels)))
return new_left_offset, new_top_offset, new_height, new_width, pixels
def trimPixels(block, left, right, upper, lower, two_dimensional_array):
# Calculate new dimensions
new_height = len(two_dimensional_array) - upper - lower
new_width = len(two_dimensional_array[0]) - left - right
new_left_offset = block.left + left
new_top_offset = block.top + upper
# Remove columns and rows
trimmed_array = [row[left:new_width + left] for row in
two_dimensional_array[upper:new_height + upper]]
return new_left_offset, new_top_offset, new_height, new_width, trimmed_array
def findBoundaries(block, reader, two_dimensional_array):
# Initialize variables to store corner positions
left, upper, right, lower = 0, 0, 0, 0
for x in range(block.width):
all_black = 1
for y in range(block.height):
pixel = two_dimensional_array[y][x]
color = (block.color_table or reader.color_table)[pixel]
if color != (0, 0, 0) and color != (255, 255, 255):
all_black = 0
break
if all_black:
left += 1
else:
break
for x in range(block.width):
all_black = 1
for y in range(block.height):
pixel = two_dimensional_array[y][block.width - x - 1]
color = (block.color_table or reader.color_table)[pixel]
if color != (0, 0, 0) and color != (255, 255, 255):
all_black = 0
break
if all_black:
right += 1
else:
break
for y in range(block.height):
all_black = 1
for x in range(block.width):
pixel = two_dimensional_array[y][x]
color = (block.color_table or reader.color_table)[pixel]
if color != (0, 0, 0) and color != (255, 255, 255):
all_black = 0
break
if all_black:
upper += 1
else:
break
for y in range(block.height):
all_black = 1
for x in range(block.width):
pixel = two_dimensional_array[block.height - y - 1][x]
color = (block.color_table or reader.color_table)[pixel]
if color != (0, 0, 0) and color != (255, 255, 255):
all_black = 0
break
if all_black:
lower += 1
else:
break
if left + right >= block.width:
left = block.width - 1
right = 0
if lower + upper >= block.height:
upper = block.height - 1
lower = 0
return left, lower, right, upper
def optimizeImagesInFolder(folder):
gifs = [f for f in listdir(folder) if isfile(join(folder, f)) and splitext(f)[1] == ".gif"]
gifs.sort()
for file in gifs:
optimizeImage(join(folder, file))
optimizeImage("c:\\work\\Repository\\Knomi\\Firmware\\data\\cp.gif")
#optimizeImagesInFolder("c:\\work\\Repository\\Knomi\\Firmware\\data")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment