@ Pohon BBS
GIF contrast adjustment (1 reply)

#1. GIF contrast adjustment
Published: 2025-06-09 [Mon] 11:27, by blap
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
gifedit.py - Adjust contrast of a GIF by modifying its color palette.

Shouldn't touch anything but palette.

Usage:./gifedit.py input.gif contrast_factor

- input.gif: Path to the input GIF file.
- contrast_factor: Floating point number where 1.0 is identity,
>1.0 increases contrast, and <1.0 decreases contrast.

Output: A new GIF file with the contrast-adjusted palette, named after the input file with '_contrast_{factor}.gif' appended.
"""

import sys
import os
import struct

def adjust_contrast(rgb, factor):
"""
Apply contrast adjustment to a given RGB value.

:param rgb: The RGB value to adjust (as a tuple).
:param factor: Contrast factor (1.0 = no change, >1.0 increase, <1.0 decrease).
:return: Adjusted RGB value.
"""
r, g, b = rgb
r = int(((r / 255.0 - 0.5) * factor + 0.5) * 255.0)
g = int(((g / 255.0 - 0.5) * factor + 0.5) * 255.0)
b = int(((b / 255.0 - 0.5) * factor + 0.5) * 255.0)
return (max(0, min(255, r)), max(0, min(255, g)), max(0, min(255, b)))
def main():
if len(sys.argv)!= 3:
print("Usage:./gifedit.py input.gif contrast_factor")
sys.exit(1)

input_file = sys.argv[1]
try:
contrast_factor = float(sys.argv[2])
except ValueError:
print("Error: Contrast factor must be a floating point number.")
sys.exit(1)

if contrast_factor <= 0:
print("Warning: Contrast factor should be greater than zero. Proceeding with value:", contrast_factor)

# Load the GIF
try:
with open(input_file, 'rb') as f_in:
gif_data = f_in.read()

# Verify the GIF magic bytes
if gif_data[:6] not in [b'GIF87a', b'GIF89a']:
print("Error: Not a GIF file.")
sys.exit(1)

# Get the original file name without extension
filename, file_extension = os.path.splitext(input_file)
output_file = f"{filename}_contrast_{contrast_factor:.2f}{file_extension}"

# Determine the GCT size
gct_size_byte = gif_data[10] # 10th byte indicates GCT size (2^(N+1))
gct_size = 2 ** ((gct_size_byte & 0x07) + 1) # Extract the lower 3 bits
gct_start = 13 # GCT starts after the 12th byte (header + gct_size_byte)
gct_end = gct_start + gct_size * 3

# Extract and adjust the Global Color Table
gct = gif_data[gct_start:gct_end]
adjusted_gct = bytearray()
for i in range(0, len(gct), 3):
rgb = struct.unpack('<BBB', gct[i:i+3])
adjusted_rgb = adjust_contrast(rgb, contrast_factor)
adjusted_gct.extend(adjusted_rgb)

# Replace the original GCT with the adjusted one
gif_data = gif_data[:gct_start] + adjusted_gct + gif_data[gct_end:]

# Save the modified GIF data
with open(output_file, 'wb') as f_out:
f_out.write(gif_data)
print(f"Output saved to: {output_file}")

except IOError as e:
print(f"Error opening or processing the file: {e}")

if __name__ == "__main__":
main()
.
Pohon BBS