def on_add(self, widget, copy=False): """ Add new layer to the image and a new frame to the Timeline. if copy is true them the current layer will be copy. """ # starting gimp undo group self.image.undo_group_start() name = "Frame " + str(len(self.frames)) # create the layer to add l = None if not copy: l = gimp.Layer(self.image, name, self.image.width, self.image.height, RGBA_IMAGE, 100, NORMAL_MODE) else: # copy current layer to add l = self.frames[self.active].layer.copy() l.name = name # adding layer self.image.add_layer(l, len(self.image.layers) - self.active - 1) if self.new_layer_type == TRANSPARENT_FILL and not copy: pdb.gimp_edit_clear(l) self._scan_image_layers() self.on_goto(None, NEXT, True) if len(self.frames) == 1: self._toggle_enable_buttons(NO_FRAMES) # ending gimp undo group self.image.undo_group_end()
def imgarray_to_layer(array, gimp_img, name): h, w, d = array.shape layer = gimp.Layer(gimp_img, name, w, h, image_type_map[d]) region = layer.get_pixel_rgn(0, 0, w, h) region[:, :] = array.buffer gimp_img.insert_layer(layer, position=0) return layer
def showWin(width, height): img = gimp.Image(width, height, RGB) lyr = gimp.Layer(img, 'layer1', width, height, RGB, 100, NORMAL_MODE) lyr.fill(BACKGROUND_FILL) img.add_layer(lyr) gimp.Display(img) gimp.displays_flush()
def python_text_border(image, drawable, thickness=5, colour=(0, 0, 0)): """The plugin's main function.""" text_layer = image.active_layer layer_name = text_layer.name pdb.gimp_image_select_item(image, 2, text_layer) pdb.gimp_selection_grow(image, thickness) border_layer = gimp.Layer( image, 'border', image.width, image.height, gimpfu.RGBA_IMAGE, 100, gimpfu.NORMAL_MODE) position = pdb.gimp_image_get_layer_position(image, text_layer) image.add_layer(border_layer, position + 1) old_fg = gimp.get_foreground() gimp.set_foreground(colour) pdb.gimp_edit_fill(border_layer, gimpfu.FOREGROUND_FILL) gimp.set_foreground(old_fg) layer = pdb.gimp_image_merge_down(image, text_layer, 0) pdb.gimp_layer_set_name(layer, layer_name)
def make_captcha(sx, sy, font_height, letter_spacing, left_margin, angle_range, fonts, answer): """Generate a captcha consisting of the letters in answer. :rtype: :class:`gimp.Image` :returns: The CAPTCHA as a gimp-python image object. """ img = gimp.Image(sx, sy, RGB_IMAGE) img.disable_undo() light_noise_layer = gimp.Layer(img, 'light noise', sx, sy, RGB_IMAGE, 100, NORMAL_MODE) img.add_layer(light_noise_layer, 0) gpdb.gimp_selection_none(img) gpdb.gimp_drawable_fill(light_noise_layer, WHITE_FILL) # plug_in_randomize_hurl at 1% 1 time is vastly superior to # scatter_rgb here, but has a bug where it creates an artifact at # the top of the image when invoked in a scripting context like # this. # # Future experiment: dial down the amount of noise generated by # scatter, then run it through levels to darken it, then # blur. This should be equivalent to hurl + blur. #gpdb.plug_in_randomize_hurl(img, light_noise_layer, 1, 1, 0, 0) gpdb.plug_in_scatter_hsv(img, light_noise_layer, 1, 25, 200, 180) gpdb.plug_in_gauss_iir(img, light_noise_layer, 1, 1, 1) gpdb.gimp_desaturate(light_noise_layer) # Next make pure black layer which we will copy repeatedly as a # place to cut out letters. blackLayer = gimp.Layer(img, 'black', sx, sy, RGB_IMAGE, 100, NORMAL_MODE) img.add_layer(blackLayer, 0) blackLayer.add_alpha() gpdb.gimp_layer_add_alpha(blackLayer) gpdb.gimp_drawable_fill(blackLayer, WHITE_FILL) gpdb.gimp_invert(blackLayer) # Loop through each letter, making it a separate black layer. right = left_margin last_substrate = None for letter in answer: font = random.choice(FONTS) substrate = blackLayer.copy() img.add_layer(substrate, 0) new_right = cookie_cutter_letter(img, substrate, right, font, letter) # look out for really narrow letters if new_right - right < 20: new_right += 5 right = new_right img.remove_layer(blackLayer) # Hide the light noise layer, then collapse all the remaining # layers (all letters) into a single layer. light_noise_layer.visible = False textLayer = gpdb.gimp_image_merge_visible_layers(img, CLIP_TO_IMAGE) light_noise_layer.visible = True # Create a layer of dark noise which will display the letters. dark_noise_layer = gimp.Layer(img, 'dark noise', sx, sy, RGB_IMAGE, 100, MULTIPLY_MODE) img.add_layer(dark_noise_layer, 1) gpdb.gimp_drawable_fill(dark_noise_layer, WHITE_FILL) gpdb.plug_in_randomize_hurl(img, dark_noise_layer, 25, 1, 0, 0) gpdb.gimp_desaturate(dark_noise_layer) # These next operations are ordered carefully. Changing the order # dramatically affects how the output looks. # Here's where we do the cutout operation. gpdb.gimp_selection_layer_alpha(textLayer) gpdb.gimp_selection_invert(img) gpdb.gimp_edit_clear(dark_noise_layer) gpdb.gimp_selection_none(img) # After the cutout, blur the dark noise layer and then darken it: gpdb.plug_in_gauss_iir(img, dark_noise_layer, 1, 1, 1) gpdb.gimp_levels(dark_noise_layer, HISTOGRAM_VALUE, 127, 255, 0.25, 0, 255) textLayer.visible = False # If you start gimp without --no-interface with an X server, this # line will let you see the image looks like at this point in the # script, layers and all. It should be fine to move this line to # any problematic part of the script for debugging. # # gimp.Display(gpdb.gimp_image_duplicate(img)) final = img.flatten() gpdb.gimp_image_clean_all(img) img.enable_undo() return img, final
def draw(dst_image, copy_and_rotate_definitions): """Copies regions from the input image to a wrap image.""" dst_layer = gimp.Layer(dst_image, "Wrap", dst_image_width, dst_image_height, gimpfu.RGB_IMAGE, 100, gimpfu.NORMAL_MODE) # type: gimp.Layer dst_layer.fill(gimpfu.WHITE_FILL) dst_image.add_layer(dst_layer, 0) # Add guides for x in dst_xs: # type: int dst_image.add_vguide(x) for y in dst_ys: # type: int dst_image.add_hguide(y) # Take the layers from the template and move and rotate them # into position for d in copy_and_rotate_definitions: pdb.gimp_progress_pulse() copy_and_rotate_rectangle( src_image, # src_image d[0], # src_x d[1], # src_y d[2], # src_width d[3], # src_height dst_layer, # dst_layer d[4], # dst_x d[5], # dst_y d[6], # dst_corner d[7]) # rotation_angle # Copy strips from the sides to create the flaps on the front # and the back pdb.gimp_progress_pulse() copy_and_rotate_rectangle(dst_image, dst_xs[1], dst_ys[4], half_box_height_plus_extra, flap_size, dst_layer, dst_xs[5], dst_ys[4], Corner.BOTTOM_RIGHT, 90) pdb.gimp_progress_pulse() copy_and_rotate_rectangle(dst_image, dst_xs[1], dst_ys[6], half_box_height_plus_extra, flap_size, dst_layer, dst_xs[5], dst_ys[7], Corner.TOP_RIGHT, 270) pdb.gimp_progress_pulse() copy_and_rotate_rectangle(dst_image, dst_xs[6], dst_ys[4], half_box_height_plus_extra, flap_size, dst_layer, dst_xs[6], dst_ys[4], Corner.BOTTOM_LEFT, 270) pdb.gimp_progress_pulse() copy_and_rotate_rectangle(dst_image, dst_xs[6], dst_ys[6], half_box_height_plus_extra, flap_size, dst_layer, dst_xs[6], dst_ys[7], Corner.TOP_LEFT, 90) # Marks for cutting and folding draw_mark(dst_image, (Direction.UP, Direction.LEFT), dst_xs[4], dst_ys[1], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.UP, ), dst_xs[5], dst_ys[1], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.UP, ), dst_xs[6], dst_ys[1], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.UP, Direction.RIGHT), dst_xs[7], dst_ys[1], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.UP, Direction.LEFT), dst_xs[1], dst_ys[4], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.UP, Direction.RIGHT), dst_xs[10], dst_ys[4], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, Direction.LEFT), dst_xs[1], dst_ys[7], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, Direction.RIGHT), dst_xs[10], dst_ys[7], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, Direction.LEFT), dst_xs[4], dst_ys[10], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, ), dst_xs[5], dst_ys[10], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, ), dst_xs[6], dst_ys[10], crop_mark_size, crop_mark_distance) draw_mark(dst_image, (Direction.DOWN, Direction.RIGHT), dst_xs[7], dst_ys[10], crop_mark_size, crop_mark_distance) pdb.gimp_selection_none(dst_image)
def create_template( box_width_mm, # type: float box_height_mm, # type: float box_depth_mm # type: float ): # type: (...) -> None """Creates an empty template image given the box size.""" with DefaultContext(): box_width = mm_to_px(box_width_mm) # type: int box_height = mm_to_px(box_height_mm) # type: int box_depth = mm_to_px(box_depth_mm) # type: int xs, ys = template_coordinates(box_width, box_height, box_depth) image_width = xs[-1] - xs[0] # type: int image_height = ys[-1] - ys[0] # type: int # Create a template image with one transparent layer image = gimp.Image(image_width, image_height) # type: gimp.Image with PausedUndo(image): layer = gimp.Layer(image, "Template", image_width, image_height, gimpfu.RGBA_IMAGE, 100, gimpfu.NORMAL_MODE) # type: gimp.Layer image.add_layer(layer, 0) # Create guides for x in xs: # type: int image.add_vguide(x) for y in ys: # type: int image.add_hguide(y) # Fill the areas where the graphics go with white pdb.gimp_selection_none(image) pdb.gimp_progress_pulse() pdb.gimp_image_select_rectangle(image, gimpfu.CHANNEL_OP_ADD, xs[0], ys[1], image_width, ys[3] - ys[1]) pdb.gimp_progress_pulse() pdb.gimp_image_select_rectangle(image, gimpfu.CHANNEL_OP_ADD, xs[1], ys[0], xs[2] - xs[1], image_height) pdb.gimp_edit_fill(layer, gimpfu.WHITE_FILL) pdb.gimp_selection_none(image) def put_text(text, left, right, top, bottom): """Puts some text in the center of a rectangle.""" pdb.gimp_progress_pulse() text_size = DPI / 4 # type: int text_layer = pdb.gimp_text_layer_new( image, text, "sans-serif", text_size, gimpfu.PIXELS) # type: gimp.Layer image.add_layer(text_layer, 0) move_drawable_to(text_layer, Corner.CENTER, (left + right) // 2, (top + bottom) // 2) pdb.gimp_image_merge_down(image, text_layer, gimpfu.CLIP_TO_BOTTOM_LAYER) put_text("TOP", xs[1], xs[2], ys[0], ys[1]) put_text("LEFT", xs[0], xs[1], ys[1], ys[3]) put_text("FRONT", xs[1], xs[2], ys[1], ys[3]) put_text("RIGHT", xs[2], xs[3], ys[1], ys[3]) put_text("BACK", xs[3], xs[4], ys[1], ys[3]) put_text("BOTTOM", xs[1], xs[2], ys[3], ys[4]) put_text( "Box width: %dmm (%dpx)\n" "Box height: %dmm (%dpx)\n" "Box depth: %dmm (%dpx)" % (box_width_mm, box_width, box_height_mm, box_height, box_depth_mm, box_depth), xs[0], xs[1], ys[0], ys[1]) gimp.Display(image) gimp.displays_flush()