GIF contrast adjustment Anonymous https://bbs.gikopoi.com/atom/thread/1749468433 2025-06-09T11:27:13+00:00 GIF contrast adjustment https://bbs.gikopoi.com/post/1749468433/1 2025-06-09T11:27:13+00:00 2025-06-09T11:27:13+00:00 #!/usr/bin/env python3<br># -*- coding: utf-8 -*-<br><br>"""<br>gifedit.py - Adjust contrast of a GIF by modifying its color palette.<br><br>Shouldn't touch anything but palette.<br><br>Usage:./gifedit.py input.gif contrast_factor<br><br>- input.gif: Path to the input GIF file.<br>- contrast_factor: Floating point number where 1.0 is identity, <br> >1.0 increases contrast, and <1.0 decreases contrast.<br><br>Output: A new GIF file with the contrast-adjusted palette, named after the input file with '_contrast_{factor}.gif' appended.<br>"""<br><br>import sys<br>import os<br>import struct<br><br>def adjust_contrast(rgb, factor):<br> """<br> Apply contrast adjustment to a given RGB value.<br><br> :param rgb: The RGB value to adjust (as a tuple).<br> :param factor: Contrast factor (1.0 = no change, >1.0 increase, <1.0 decrease).<br> :return: Adjusted RGB value.<br> """<br> r, g, b = rgb<br> r = int(((r / 255.0 - 0.5) * factor + 0.5) * 255.0)<br> g = int(((g / 255.0 - 0.5) * factor + 0.5) * 255.0)<br> b = int(((b / 255.0 - 0.5) * factor + 0.5) * 255.0)<br> return (max(0, min(255, r)), max(0, min(255, g)), max(0, min(255, b)))<br>def main():<br> if len(sys.argv)!= 3:<br> print("Usage:./gifedit.py input.gif contrast_factor")<br> sys.exit(1)<br><br> input_file = sys.argv[1]<br> try:<br> contrast_factor = float(sys.argv[2])<br> except ValueError:<br> print("Error: Contrast factor must be a floating point number.")<br> sys.exit(1)<br><br> if contrast_factor <= 0:<br> print("Warning: Contrast factor should be greater than zero. Proceeding with value:", contrast_factor)<br><br> # Load the GIF<br> try:<br> with open(input_file, 'rb') as f_in:<br> gif_data = f_in.read()<br><br> # Verify the GIF magic bytes<br> if gif_data[:6] not in [b'GIF87a', b'GIF89a']:<br> print("Error: Not a GIF file.")<br> sys.exit(1)<br><br> # Get the original file name without extension<br> filename, file_extension = os.path.splitext(input_file)<br> output_file = f"{filename}_contrast_{contrast_factor:.2f}{file_extension}"<br><br> # Determine the GCT size<br> gct_size_byte = gif_data[10] # 10th byte indicates GCT size (2^(N+1))<br> gct_size = 2 ** ((gct_size_byte & 0x07) + 1) # Extract the lower 3 bits<br> gct_start = 13 # GCT starts after the 12th byte (header + gct_size_byte)<br> gct_end = gct_start + gct_size * 3<br><br> # Extract and adjust the Global Color Table<br> gct = gif_data[gct_start:gct_end]<br> adjusted_gct = bytearray()<br> for i in range(0, len(gct), 3):<br> rgb = struct.unpack('<BBB', gct[i:i+3])<br> adjusted_rgb = adjust_contrast(rgb, contrast_factor)<br> adjusted_gct.extend(adjusted_rgb)<br><br> # Replace the original GCT with the adjusted one<br> gif_data = gif_data[:gct_start] + adjusted_gct + gif_data[gct_end:]<br><br> # Save the modified GIF data<br> with open(output_file, 'wb') as f_out:<br> f_out.write(gif_data)<br> print(f"Output saved to: {output_file}")<br><br> except IOError as e:<br> print(f"Error opening or processing the file: {e}")<br><br>if __name__ == "__main__":<br> main()<br>