Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Exposure for Plug-in
#2
I even went as far as trying to read code gegl/exposure.c
and can't get it to produce the same
here's my python call
def simulate_gimp_exposure(img, drawable, black_level=0.002, exposure=1.696):
pdb.gimp_image_undo_group_start(img)

# Get the current layer
layer = drawable

# Get the pixel data
width, height = layer.width, layer.height

srcRgn = layer.get_pixel_rgn(0, 0, width, height,
False, False)
src_pixels = array("B", srcRgn[0:width, 0:height])

dstRgn = layer.get_pixel_rgn(0, 0, width, height,
True, True)
p_size = len(srcRgn[0,0])
dest_pixels = array("B", "\x00" * (width * height * p_size))

# white = math.pow(2.0, -exposure) # Equivalent to exp2f(-exposure)
# diff = max(white - black_level, 0.000001)
# gain = 1.0 / diff # Normalize brightness scaling
# **Apply Exposure Negation** (Key part of GIMP logic)
exposure_negated = -exposure # ✅ This is how GIMP negates exposure
white = math.pow(2.0, exposure_negated) # ✅ Equivalent to exp2f(exposure_negated)

# Ensure we don't divide by zero in the gain calculation
diff = max(white - black_level, 0.000001)
gain = 1.0 / diff # Normalize brightness scaling

# Read pixel data as bytes
#data = bytearray(srcRgn[0:width, 0:height]) # Convert to mutable array
data = src_pixels

# Determine number of channels (RGB = 3, RGBA = 4)
bpp = len(data) // (width * height)
p_size = bpp
dest_pixels = array("B", "\x00" * (width * height * p_size))
# Convert to float, apply black level & exposure, and store back
exposure_factor = 2**exposure
for i in range(0, len(data), bpp):
r, g, b = [float(data[i + j])/255.0 for j in range(3)]
a = data[i+3]

# **Apply GIMP Exposure Math**
r = (r - black_level) * gain
g = (g - black_level) * gain
b = (b - black_level) * gain

# Clip values to (0,1) range
r, g, b = [min(max(x, 0.0), 1.0) for x in (r, g, b)]

# Convert back to 8-bit (0-255)
r, g, b = [int(x * 255) for x in (r, g, b)]

dest_pixels[i] = r
dest_pixels[i+1] = g
dest_pixels[i+2] = b
dest_pixels[i+3] = a

# Copy the whole array back to the pixel region:


# Apply modified data back to the image

#pixel_rgn[0:width, 0:height] = bytes(data)
#pixel_rgn.set_pixels(0, 0, width, height, bytes(data))
dstRgn[0:width, 0:height] = dest_pixels.tostring()
#pixel_rgn[0:width, 0:height] = dest_pixels.tostring()
layer.flush()
layer.merge_shadow(True)
layer.update(0, 0, width, height) # Mark the region as modified
pdb.gimp_image_undo_group_end(img)
pdb.gimp_displays_flush()
Reply


Messages In This Thread
Exposure for Plug-in - by trandoductin - 02-13-2025, 02:42 PM
RE: Exposure for Plug-in - by trandoductin - 02-13-2025, 09:29 PM
RE: Exposure for Plug-in - by Ofnuts - 02-13-2025, 09:43 PM
RE: Exposure for Plug-in - by Ofnuts - 02-13-2025, 09:37 PM
RE: Exposure for Plug-in - by trandoductin - 02-14-2025, 12:17 AM
RE: Exposure for Plug-in - by Ofnuts - 02-14-2025, 09:14 AM
RE: Exposure for Plug-in - by trandoductin - 02-16-2025, 03:10 AM
RE: Exposure for Plug-in - by Ofnuts - 02-16-2025, 10:02 AM
RE: Exposure for Plug-in - by rich2005 - 02-16-2025, 09:15 AM
RE: Exposure for Plug-in - by trandoductin - 02-16-2025, 10:23 AM
RE: Exposure for Plug-in - by Ofnuts - 02-16-2025, 05:52 PM

Forum Jump: