def png(image=None): if not image: image = gimp.image_list()[0] prefix = pdb.gimp_image_get_filename(image)[:-4] + "_" gimp.progress_init("Save frames as {}_*.png".format(prefix)) for (layer_index, layer) in enumerate(image.layers): try: filename = "{}{:02d}.png".format(prefix, int(layer.name)) except ValueError: filename = "{}{}.png".format(prefix, layer.name) pdb.file_png_save( image, layer, filename, None, True, # interlace 9, # compression True, # bkgd True, # gama True, # offs True, # phys True, # time ) gimp.progress_update(100 * (layer_index + 1) / len(image.layers)) gimp.message("All frames saved as {}_*.png".format(prefix))
def ConvertColormap(image, lut): nbytes, colormap = pdb.gimp_image_get_colormap(image) max_progress = nbytes # Create empty colormap ncolomap = [] # For progress bar progress = 0 # Fill new colormap by converting from old colormap for ii in xrange(nbytes / 3): valshl1, valnor1, shad1, high1 = lut[colormap[3 * ii + 0]] valshl2, valnor2, shad2, high2 = lut[colormap[3 * ii + 1]] valshl3, valnor3, shad3, high3 = lut[colormap[3 * ii + 2]] if shad1 == shad2 == shad3 == True or high1 == high2 == high3 == True: ncolomap.append(valshl1) ncolomap.append(valshl2) ncolomap.append(valshl3) else: ncolomap.append(valnor1) ncolomap.append(valnor2) ncolomap.append(valnor3) progress = progress + 3 gimp.progress_update(float(progress) / max_progress) # Activate the new colormap pdb.gimp_image_set_colormap(image, nbytes, ncolomap) gimp.displays_flush()
def halftone_layer(img, layer, layer_dest, density, color, circle_size, black_strength): """ halftone the layer """ gimp.progress_init("Generating " + layer_dest.name) circles_count = 0 start = timer() source_region = layer.get_pixel_rgn(0, 0, layer.width, layer.height, False, False) pixel_size = len(source_region[0, 0]) source_pixels = array("B", source_region[0:layer.width, 0:layer.height]) print(pixel_size, len(source_pixels)) region = layer_dest.get_pixel_rgn(0, 0, layer_dest.width, layer_dest.height, True, True) # pixel_size = 4 n = layer_dest.width * layer_dest.height pixels = array("B", "\xFF" * (n * pixel_size)) for i in range(0, (layer.height / density) + 1): for j in range(0, (layer.width / density) + 1): percent = ((i * layer.width + j) / float( (layer.height * layer.width))) * density gimp.progress_update(percent) x = j * density y = i * density x_2 = x + density if x + density < layer.width else layer.width y_2 = y + density if y + density < layer.height else layer.height if x_2 == x or y_2 == y: continue box = (x, y, x_2, y_2) mean_bright = get_mean_brightness(source_pixels, box, layer.width, layer.height, pixel_size) max_strength = 255 if color == (0, 0, 0, 255): # manage black strength max_strength = 510 - black_strength isz = get_value_in_range(mean_bright, 0, max_strength, 0, circle_size) if isz > 0: circles_count += 1 draw_circle_on_pixels_region(pixels, layer_dest.width, layer_dest.height, x + density / 2, y + density / 2, isz, color) # Write our changes back over the original layer region[0:layer_dest.width, 0:layer_dest.height] = pixels.tostring() layer_dest.flush() layer_dest.merge_shadow(True) layer_dest.update(0, 0, layer_dest.width, layer_dest.height) pdb.gimp_progress_end() end = timer() print(circles_count, 'in', end - start, float(end - start) / circles_count)
def MDFade(image, layer, srcmode, dstmode, fademode): srclut = SelectSrcLUT(srcmode) dstlut = SelectDstLUT(dstmode) gimp.progress_init("Generating palette fade...") pdb.gimp_image_undo_group_start(image) # Get the layer position. pos = FindLayer(image, layer) srcWhite = FindColor(255, srcmode) if (fademode == FadeMode.CurrentToBlack): conv = lambda jj, ss: (jj * (15 - ss)) // 15 elif (fademode == FadeMode.BlackToCurrent): conv = lambda jj, ss: (jj * ss) // 15 elif (fademode == FadeMode.CurrentToWhite): conv = lambda jj, ss: (jj * (15 - ss) + srcWhite * ss) // 15 else: #if (fademode == FadeMode.WhiteToCurrent): conv = lambda jj, ss: (jj * ss + srcWhite * (15 - ss)) // 15 finalLayer = None for step in xrange(15): lut = { chr(ii): chr(dstlut[srclut[conv(ii, step)]]) for ii in xrange(256) } # Create a new layer to save the results (otherwise is not possible to undo the operation). newLayer = layer.copy() image.add_layer(newLayer, pos) # Clear the new layer. pdb.gimp_edit_clear(newLayer) newLayer.flush() # Calculate the number of tiles. tile_width = gimp.tile_width() tile_height = gimp.tile_height() # Ceiling division width_tiles = -(-layer.width // tile_width) height_tiles = -(-layer.height // tile_height) # Iterate over the tiles. for col in xrange(width_tiles): for row in xrange(height_tiles): # Update the progress bar. gimp.progress_update( float(step * width_tiles * height_tiles + col * height_tiles + row) / float(15 * width_tiles * height_tiles)) ConvertTileNoSHL(layer.get_tile(False, row, col), newLayer.get_tile(False, row, col), lut) # Update the new layer. newLayer.flush() newLayer.merge_shadow(True) newLayer.update(0, 0, layer.width, layer.height) finalLayer = newLayer # Remove the old layer. if finalLayer is not None: layerName = layer.name image.remove_layer(layer) finalLayer.name = layerName gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def __pauseAndProgressDisplay(self, sleep_seconds): """ Pause the execution of the program and update the Progress indicator in GIMPs GUI panel. Parameters: sleep_seconds (Int) : The number of seconds the program should sleep for. Returns: NA Invoked by : Many procedures. Invokes : NA """ nameProcedure = "OverlayImageAgent::pauseAndProgressDisplay" counter_max = 100 counter = 0 print("%s : Enter" % (nameProcedure)) if sleep_seconds > 0: while counter < counter_max: time.sleep(float(sleep_seconds) / float(counter_max)) counter = counter + 1 gimp.progress_update(float(counter) / float(counter_max)) print("%s : Exit" % (nameProcedure))
def gif(image=None, suffix=None, fps=24): if not image: image = gimp.image_list()[0] file_path = pdb.gimp_image_get_filename(image)[:-4] if suffix: file_path += "_" + suffix.strip() file_path += ".gif" ms = int(1000.0 / fps) temp_image = False try: gimp.progress_init( "Save animated GIF @ {} fps = {} ms/frame as {}".format( fps, ms, file_path)) if pdb.gimp_image_base_type(image) != 2: temp_image = True image = pdb.gimp_image_duplicate(image) pdb.gimp_image_convert_indexed( image, 0, # dither-type=CONVERT-DITHER-NONE 0, # palette-type=CONVERT-PALETTE-GENERATE 255, # num-cols False, # alpha-dither False, # remove-unused "" # palette ) gimp.progress_update(50) pdb.file_gif_save( image, image.layers[0], file_path, file_path, True, # interlace True, # loop ms, # default-delay 2 # default-dispose ) gimp.progress_update(100) gimp.message("Saved animated GIF @ {} fps = {} ms/frame as {}".format( fps, ms, file_path)) finally: if temp_image: pdb.gimp_image_delete(image)
def MDColors(image, layer, srcmode, dstmode, shlmode): lut = BuildColorLUT(srcmode, dstmode, shlmode) gimp.progress_init("Converting to MD colors...") # Indexed images are faster if layer.is_indexed: ConvertColormap(image, lut) else: pdb.gimp_image_undo_group_start(image) # Get the layer position. pos = FindLayer(image, layer) # Create a new layer to save the results (otherwise is not possible to undo the operation). newLayer = layer.copy() image.add_layer(newLayer, pos) layerName = layer.name # Clear the new layer. pdb.gimp_edit_clear(newLayer) newLayer.flush() # Calculate the number of tiles. tile_width = gimp.tile_width() tile_height = gimp.tile_height() # Ceiling division width_tiles = -(-layer.width // tile_width) height_tiles = -(-layer.height // tile_height) # Iterate over the tiles. for col in xrange(width_tiles): for row in xrange(height_tiles): # Update the progress bar. gimp.progress_update( float(col * height_tiles + row) / float(width_tiles * height_tiles)) ConvertTile(layer.get_tile(False, row, col), newLayer.get_tile(False, row, col), lut) # Update the new layer. newLayer.flush() newLayer.merge_shadow(True) newLayer.update(0, 0, layer.width, layer.height) # Remove the old layer. image.remove_layer(layer) newLayer.name = layerName # Update display and finish undo group. gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def sheet(image=None, cols=0): if not image: image = gimp.image_list()[0] if not cols: best = (1, 10000000) for cols in range(1, len(image.layers) + 1): rows = (len(image.layers) + (cols - 1)) // cols (sheet_width, sheet_height) = (cols * image.width, rows * image.height) sheet_aspect_ratio = sheet_width / sheet_height if sheet_width > sheet_height else sheet_height / sheet_width if sheet_aspect_ratio < best[1]: best = (cols, sheet_aspect_ratio) cols = best[0] file_path = "{}_sheet_{}_frames_{}_columns_{}x{}.png".format( pdb.gimp_image_get_filename(image)[:-4], len(image.layers), cols, image.width, image.height) gimp.progress_init("Save sheet as {}".format(file_path)) rows = (len(image.layers) + (cols - 1)) // cols sheet = pdb.gimp_image_new(image.width * cols, image.height * rows, 0) try: sheet_layer = pdb.gimp_layer_new( sheet, sheet.width, sheet.height, 1, # type = RGBA-IMAGE "sprite sheet", 100, # opacity = 100 % 0 # mode = LAYER-MODE-NORMAL-LEGACY ) pdb.gimp_image_insert_layer(sheet, sheet_layer, None, 0) (row, col) = (0, 0) for (layer_index, layer) in enumerate(image.layers): pdb.gimp_selection_none(image) pdb.gimp_layer_resize_to_image_size(layer) pdb.gimp_edit_copy(layer) floating = pdb.gimp_edit_paste(sheet_layer, True) (left, top) = floating.offsets pdb.gimp_layer_translate(floating, col * image.width - left, row * image.height - top) pdb.gimp_floating_sel_anchor(floating) col += 1 if col >= cols: col = 0 row += 1 gimp.progress_update(100 * (layer_index + 1) / len(image.layers)) pdb.file_png_save( sheet, sheet_layer, file_path, None, True, # interlace 9, # compression True, # bkgd True, # gama True, # offs True, # phys True, # time ) gimp.message("All frames saved as {}".format(file_path)) finally: pdb.gimp_image_delete(sheet)
def progress_update(self, percent): from gimpfu import gimp gimp.progress_update(percent)
def add_cmyk_layers(img, layer): """ decompose layer in cmyk components """ # Obtain layer dimensions. width = layer.width height = layer.height # Make sure this layer supports alpha so we can write to each pixel's alpha # component layer.add_alpha() for k in range(0, 4): # Grab a pixel region (readonly) covering the entire image and copy # pixel data into an array source_region = layer.get_pixel_rgn(0, 0, width, height, False, False) source_pixels = array("B", source_region[0:width, 0:height]) pixel_size = len(source_region[0, 0]) print("pixel_size", pixel_size) # Create component layer in the Image component_layer = pdb.gimp_layer_new(img, width, height, RGBA_IMAGE, COMPONENT_STRING[k], 100, LAYER_MODE_NORMAL) pdb.gimp_image_insert_layer(img, component_layer, None, 0) pdb.gimp_drawable_fill(component_layer, FILL_WHITE) # Create another region (writeable) and an array that can store all # our modified pixels component_region = component_layer.get_pixel_rgn( 0, 0, width, height, True, True) component_pixels = array("B", "\x00" * (width * height * pixel_size)) gimp.progress_init("getting " + COMPONENT_STRING[k] + " component layer...") x = 0 y = 0 # Loop through every pixel in the image/layer for y in xrange(0, (height - 1)): for x in xrange(0, (width - 1)): gimp.progress_update(1.0 * y / height) source_index = (x + width * y) * pixel_size pixel = source_pixels[source_index:source_index + pixel_size] # Write the modified pixel out to our destination array component_pixel = pixel # intensity = 0 if k == 3: # black specific intensity = pixel[k] # intensity = int(round(pixel[0] * 0.2126 + # pixel[1] * 0.7152 + # pixel[2] * 0.0722)) # c_linear = (pixel[0] / 255.0) * 0.2126 # + (pixel[1] / 255.0) * 0.7152 # + (pixel[2] / 255.0) * 0.0722 # intensity = 12.92 * c_linear if c_linear <= 0.0031308 else 1.055 * \ # pow(c_linear, 1/2.4) - 0.055 # intensity = int(round(intensity*255.0)) intensity = int( round(pixel[0] * 0.299 + pixel[1] * 0.587 + pixel[2] * 0.114)) else: intensity = pixel[k] component_pixel[3] = (255 - intensity) component_pixel[0] = COLORS[k][0] component_pixel[1] = COLORS[k][1] component_pixel[2] = COLORS[k][2] component_pixels[source_index:source_index + pixel_size] = component_pixel # Copy the whole array into the writeable pixel region component_region[0:width, 0:height] = component_pixels.tostring() # Write our changes back over the original layer component_layer.flush() component_layer.merge_shadow(True) component_layer.update(0, 0, width, height) pdb.gimp_progress_end() pdb.gimp_displays_flush()