Created
October 30, 2023 10:02
-
-
Save DiverOfDark/bdcb5fddb2499d465f2a312d2f03a585 to your computer and use it in GitHub Desktop.
naive python gif crop
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
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") |
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
pygif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment