def shift_colors_main(image, drawable, level): (bx1, by1, bx2, by2) = drawable.mask_bounds pdb.gimp_image_undo_group_start(image) #dummy funkce (vubec nic nedela, slouzi pro nastaveni undo) pdb.gimp_levels(drawable, HISTOGRAM_VALUE, 0, 255, 1.0, 0, 255) bw = bx2 - bx1 bh = by2 - by1 bpp = drawable.bpp #nacteni pixlu src_rgn = drawable.get_pixel_rgn(0, 0, image.width, image.height) src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) np_array = np.array(src_pixels) * level np_array = np_array.astype(int) np_array = np.minimum(np.maximum(np_array, 0), 255) tmp_array = array.array('B', np_array) src_rgn[bx1:bx2, by1:by2] = tmp_array.tostring() drawable.flush() drawable.update(0, 0, image.width, image.height) gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def jetkiller(img, colormap, ignore_gray): img.undo_group_start() gimp.progress_init("Executing Jet Killer ...") src_layer = img.active_layer w = src_layer.width h = src_layer.height dst_layer = gimp.Layer(img, src_layer.name + " - Jet Killer", w, h, gimpenums.RGBA_IMAGE) dst_layer.set_offsets( *src_layer.offsets) # at the same position as the source img.add_layer(dst_layer) # on top by default input_cmap = get_colormap("jet") output_cmap = get_colormap(colormap) def raw_convert_pixel(px): # Get nearest color from input colormap and return # corresponding color in output colormap dr = input_cmap[:, 0] - ord(px[0]) dg = input_cmap[:, 1] - ord(px[1]) db = input_cmap[:, 2] - ord(px[2]) dist = dr * dr + dg * dg + db * db idx = np.argmin(dist) return "".join([chr(j) for j in output_cmap[idx]]) cache = {} def convert_pixel(px): if px not in cache: cache[px] = raw_convert_pixel(px) return cache[px] gimp.tile_cache_ntiles(_tile_cache_size) src_rgn = src_layer.get_pixel_rgn(0, 0, src_layer.width, src_layer.height, False, False) dst_rgn = dst_layer.get_pixel_rgn(0, 0, dst_layer.width, dst_layer.height, True, True) for x in xrange(src_layer.width): for y in xrange(src_layer.height): pixel = src_rgn[x, y] if not ignore_gray or (pixel[0] != pixel[1] or pixel[1] != pixel[2]): new_rgb_pixel = convert_pixel(pixel[0:3]) if len(pixel) == 4: # has an alpha channel new_rgba_pixel = new_rgb_pixel + pixel[3] else: new_rgba_pixel = new_rgb_pixel + chr(255) dst_rgn[x, y] = new_rgba_pixel gimp.progress_update(float(x) / src_layer.width) # update progress bar dst_layer.flush() dst_layer.merge_shadow() dst_layer.update(0, 0, dst_layer.width, dst_layer.height) gimp.pdb.gimp_progress_end() # important for non-interactive mode gimp.displays_flush() img.undo_group_end()
def makePreviewLayer(self, img, layer): lNewPreviewLayer = None pdb.gimp_image_undo_freeze(self.img) #Apply selection pdb.gimp_image_select_item(self.img, 2, self.userSelectionChan) #Preform Copy pdb.gimp_edit_copy(layer) floatLayer = pdb.gimp_edit_paste(layer, True) pdb.gimp_floating_sel_to_layer(floatLayer) lNewPreviewLayer = pdb.gimp_image_get_active_layer(img) lNewPreviewLayer.name = "(Do Not Edit) Select Move Layers" #Preform Move #transform_2d(source_x, source_y, scale_x, scale_y, angle, dest_x, dest_y, transform_direction, interpolation) #floatLayer=lNewPreviewLayer.transform_2d(curLayer.offsets[0], curLayer.offsets[1], 1, 1, 0, curLayer.offsets[0]+xdelta, curLayer.offsets[1]+ydelta, 0, 0) self.previewPos = floatLayer.offsets lNewPreviewLayer.set_offsets(self.previewPos[0] + self.xdelta, self.previewPos[1] + self.ydelta) #Preform Anchor #pdb.gimp_floating_sel_anchor(floatLayer) pdb.gimp_image_undo_thaw(self.img) gimp.displays_flush() return lNewPreviewLayer
def removePreviews(self): if self.layer_exists(self.previewLayer): pdb.gimp_image_undo_freeze(self.img) self.img.remove_layer(self.previewLayer) pdb.gimp_image_undo_thaw(self.img) self.previewLayer = None gimp.displays_flush()
def hue_map_plugin_main(self, run_mode, image, drawable, gradient_name=None, flatten=1): #set default gradient name if gradient_name is None: gradient_name = self.default_gradient self.image = image self.drawable = drawable #create settings storage if not shelf.has_key(self.shelfkey): self.shelf_store(gradient_name, flatten) #initialize dialog self.create_dialog() #create default hue gradient if not self.gradient_exists(self.default_gradient): self.reset_gradient() pdb.gimp_image_undo_group_start(self.image) if run_mode == RUN_INTERACTIVE: #show and run the dialog self.dialog.run() #this code runs after the dialog is closed -> cleanup time! #destroy preview self.layer_destroy() else: #non-interactive or use last values self.ok_clicked(None) pdb.gimp_image_undo_group_end(self.image) #refresh gimp.displays_flush()
def updatePreviewLayer(self, widget, data=None): if self.layer_exists(self.previewLayer): self.updateTransformFromGUI() pdb.gimp_image_undo_freeze(self.img) self.previewLayer.set_offsets(self.previewPos[0] + self.xdelta, self.previewPos[1] + self.ydelta) pdb.gimp_image_undo_thaw(self.img) gimp.displays_flush()
def lbp_main(self, run_mode, image, drawable, radius=1, rad=1): #self.rad = rad self.radius = radius self.drawable = drawable self.image = image self.create_dialog() self.dialog.run() gimp.displays_flush()
def generateOnionLayer(self, onionLayer, layerName, textureAtlases, textureIdx): pdb.gimp_image_undo_freeze(self.img) try: #Save active layer activeLayer=pdb.gimp_image_get_active_layer(self.img) #Save selection origSelectionChan=pdb.gimp_selection_save(self.img) #delete old layer if self.layer_exists(onionLayer): self.img.remove_layer(onionLayer) #generate layer #( image, # width, # height, # Type { RGB-IMAGE (0), RGBA-IMAGE (1), GRAY-IMAGE (2), GRAYA-IMAGE (3), INDEXED-IMAGE (4), INDEXEDA-IMAGE (5) }, # layer Name, # The layer opacity (0 <= opacity <= 100), """ The layer combination mode { LAYER-MODE-NORMAL-LEGACY (0), LAYER-MODE-DISSOLVE (1), LAYER-MODE-BEHIND-LEGACY (2), LAYER-MODE-MULTIPLY-LEGACY (3), LAYER-MODE-SCREEN-LEGACY (4), LAYER-MODE-OVERLAY-LEGACY (5), LAYER-MODE-DIFFERENCE-LEGACY (6), LAYER-MODE-ADDITION-LEGACY (7), LAYER-MODE-SUBTRACT-LEGACY (8), LAYER-MODE-DARKEN-ONLY-LEGACY (9), LAYER-MODE-LIGHTEN-ONLY-LEGACY (10), LAYER-MODE-HSV-HUE-LEGACY (11), LAYER-MODE-HSV-SATURATION-LEGACY (12), LAYER-MODE-HSL-COLOR-LEGACY (13), LAYER-MODE-HSV-VALUE-LEGACY (14), LAYER-MODE-DIVIDE-LEGACY (15), LAYER-MODE-DODGE-LEGACY (16), LAYER-MODE-BURN-LEGACY (17), LAYER-MODE-HARDLIGHT-LEGACY (18), LAYER-MODE-SOFTLIGHT-LEGACY (19), LAYER-MODE-GRAIN-EXTRACT-LEGACY (20), LAYER-MODE-GRAIN-MERGE-LEGACY (21), LAYER-MODE-COLOR-ERASE-LEGACY (22), LAYER-MODE-OVERLAY (23), LAYER-MODE-LCH-HUE (24), LAYER-MODE-LCH-CHROMA (25), LAYER-MODE-LCH-COLOR (26), LAYER-MODE-LCH-LIGHTNESS (27), LAYER-MODE-NORMAL (28), LAYER-MODE-BEHIND (29), LAYER-MODE-MULTIPLY (30), LAYER-MODE-SCREEN (31), LAYER-MODE-DIFFERENCE (32), LAYER-MODE-ADDITION (33), LAYER-MODE-SUBTRACT (34), LAYER-MODE-DARKEN-ONLY (35), LAYER-MODE-LIGHTEN-ONLY (36), LAYER-MODE-HSV-HUE (37), LAYER-MODE-HSV-SATURATION (38), LAYER-MODE-HSL-COLOR (39), LAYER-MODE-HSV-VALUE (40), LAYER-MODE-DIVIDE (41), LAYER-MODE-DODGE (42), LAYER-MODE-BURN (43), LAYER-MODE-HARDLIGHT (44), LAYER-MODE-SOFTLIGHT (45), LAYER-MODE-GRAIN-EXTRACT (46), LAYER-MODE-GRAIN-MERGE (47), LAYER-MODE-VIVID-LIGHT (48), LAYER-MODE-PIN-LIGHT (49), LAYER-MODE-LINEAR-LIGHT (50), LAYER-MODE-HARD-MIX (51), LAYER-MODE-EXCLUSION (52), LAYER-MODE-LINEAR-BURN (53), LAYER-MODE-LUMA-DARKEN-ONLY (54), LAYER-MODE-LUMA-LIGHTEN-ONLY (55), LAYER-MODE-LUMINANCE (56), LAYER-MODE-COLOR-ERASE (57), LAYER-MODE-ERASE (58), LAYER-MODE-MERGE (59), LAYER-MODE-SPLIT (60), LAYER-MODE-PASS-THROUGH (61), LAYER-MODE-REPLACE (62), LAYER-MODE-ANTI-ERASE (63) }) """ #(image, image width, image height, RGB-Image, "Preview Onion Layer", 100% full Opacity, Normal Mode) onionLayer = pdb.gimp_layer_new(self.img, self.img.width, self.img.height, 1, layerName, 50.0, 28) pdb.gimp_image_insert_layer(self.img, onionLayer, None,0) ##Read Each subtexture and convert to a rectangle texture=textureAtlases[textureIdx] bngColor = pdb.gimp_context_get_background() for key in texture.subtextures: for subtexture in texture.subtextures[key]: #Replace Selection pdb.gimp_selection_none(self.img) selection=pdb.gimp_image_select_rectangle(self.img, 2, int(subtexture.xy[0]), int(subtexture.xy[1]), int(subtexture.size[0]), int(subtexture.size[1])) fillColor=gimpcolor.RGB(random.randrange(0, 255),random.randrange(0, 255),random.randrange(0, 255)) pdb.gimp_context_set_background(fillColor) pdb.gimp_drawable_edit_fill(onionLayer, 1) pdb.gimp_selection_none(self.img) #Restore gimp original state pdb.gimp_context_set_background(bngColor) pdb.gimp_image_set_active_layer(self.img, activeLayer) pdb.gimp_image_select_item(self.img, 2, origSelectionChan) self.img.remove_channel(origSelectionChan) except Exception as exp: error_box(traceback.format_exc()) error_box("Exception: "+str(exp)) #Update Gimp GUI gimp.displays_flush() pdb.gimp_image_undo_thaw(self.img) return onionLayer
def sepia_main(image, drawable): (bx1, by1, bx2, by2) = drawable.mask_bounds pdb.gimp_image_undo_group_start(image) #dummy funkce (slouzi kvuli nastaveni undo) pdb.gimp_levels(drawable, HISTOGRAM_VALUE, 0, 255, 1.0, 0, 255) bw = bx2 - bx1 bh = by2 - by1 bpp = drawable.bpp #nacteni pixlu src_rgn = drawable.get_pixel_rgn(0, 0, image.width, image.height) src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) for y in range(0, bh): for x in range(0, bw): pos = (x + bw * y) * bpp c_array = src_pixels[pos:(pos + bpp)] inputRed = c_array[0] inputGreen = c_array[1] inputBlue = c_array[2] outputRed = (inputRed * .393) + (inputGreen * .769) + (inputBlue * .189) outputGreen = (inputRed * .349) + (inputGreen * .686) + (inputBlue * .168) outputBlue = (inputRed * .272) + (inputGreen * .534) + (inputBlue * .131) outputRed = get_in_range(outputRed) outputGreen = get_in_range(outputGreen) outputBlue = get_in_range(outputBlue) c_array[0] = int(outputRed) c_array[1] = int(outputGreen) c_array[2] = int(outputBlue) src_pixels[pos:(pos + bpp)] = c_array src_rgn[bx1:bx2, by1:by2] = src_pixels.tostring() drawable.flush() drawable.update(0, 0, image.width, image.height) gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def _run(proc_name, params): run_mode = params[0] func = _registered_plugins_[proc_name][10] if run_mode == RUN_NONINTERACTIVE: return apply(func, params[1:]) script_params = _registered_plugins_[proc_name][8] min_args = 0 if len(params) > 1: for i in range(1, len(params)): param_type = _obj_mapping[script_params[i - 1][0]] if not isinstance(params[i], param_type): break min_args = i if len(script_params) > min_args: start_params = params[:min_args + 1] if run_mode == RUN_WITH_LAST_VALS: default_params = _get_defaults(proc_name) params = start_params + default_params[min_args:] else: params = start_params else: run_mode = RUN_NONINTERACTIVE if run_mode == RUN_INTERACTIVE: try: res = _interact(proc_name, params[1:]) except CancelError: return else: res = apply(func, params[1:]) gimp.displays_flush() return res
def _run(func_name, params): run_mode = params[0] plugin_type = _registered_plugins_[func_name][7] func = _registered_plugins_[func_name][10] if plugin_type == PLUGIN: start_params = params[1:3] extra_params = params[3:] else: start_params = () extra_params = params[1:] if run_mode == RUN_INTERACTIVE: extra_params = _interact(func_name) if extra_params == None: return elif run_mode == RUN_WITH_LAST_VALS: extra_params = _get_defaults(func_name) params = start_params + tuple(extra_params) res = apply(func, params) if run_mode != RUN_NONINTERACTIVE: gimp.displays_flush()
def preview(self, widget): ptxt = self.preview_button.get_label() if self.layer_exists(self.previewLayer): self.img.remove_layer(self.previewLayer) gimp.displays_flush() else: lmode = self.lmode_box.get_active() up = self.up_radio.get_active() inner = self.inner_radio.get_active() width = (self.width_spinner['adj'].get_value()) height = (self.height_spinner['adj'].get_value()) shape = int(self.shape_spinner['adj'].get_value()) prenoise = self.prenoise_spinner['adj'].get_value() azimuth = self.azimuth_spinner['adj'].get_value() elevation = self.elevation_spinner['adj'].get_value() depth = int(self.depth_spinner['adj'].get_value()) postblur = self.postblur_spinner['adj'].get_value() opacity = self.opacity_spinner['adj'].get_value() gloss = self.gloss_spinner['adj'].get_value() ialpha = self.ialpha_check.get_active() self.previewLayer = self.makeLayer(self.img, self.drawable, lmode, up, inner, width, height, shape, prenoise, azimuth, elevation, depth, postblur, opacity, gloss, ialpha) if ptxt == "Preview": ptxt = "Undo Preview" else: ptxt = "Preview" self.preview_button.set_label(ptxt)
def noise_main(image, drawable, level=10, separate=True): (bx1, by1, bx2, by2) = drawable.mask_bounds pdb.gimp_image_undo_group_start(image) #dummy funkce (vubec nic nedela, slouzi pro nastaveni undo) pdb.gimp_levels(drawable, HISTOGRAM_VALUE, 0, 255, 1.0, 0, 255) bw = bx2 - bx1 bh = by2 - by1 bpp = drawable.bpp #nacteni pixlu src_rgn = drawable.get_pixel_rgn(0, 0, image.width, image.height) src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) np_array = np.array(src_pixels).reshape(bh, bw, bpp) out = np.zeros([bh, bw, bpp], dtype=int) if separate: for canal in range(bpp): tmp_noise_array = np.random.uniform(-level, level, (bh, bw)) out[:, :, canal] = np_array[:, :, canal] + tmp_noise_array else: tmp_noise_array = np.random.uniform(-level, level, (bh, bw, 1)) out = np_array + tmp_noise_array out = np.minimum(np.maximum(out, 0), 255) out = out.reshape(bw * bh * bpp, 1) tmp_array = array.array('B', out) src_rgn[bx1:bx2, by1:by2] = tmp_array.tostring() drawable.flush() drawable.update(0, 0, image.width, image.height) gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def previewButton(self, widget): ptxt = self.preview_button.get_label() if self.layer_exists(self.previewLayer): #Remove Preview self.img.remove_layer(self.previewLayer) gimp.displays_flush() self.previewLayerButton.set_sensitive(True) else: self.updateTransformFromGUI() #Add/Update Preview lPreviewLayer = None if self.userPreviewLayer is not None: self.previewLayer = self.makePreviewLayer( self.img, self.userPreviewLayer) self.previewLayerButton.set_sensitive(False) if ptxt == "Preview": ptxt = "Undo Preview" else: ptxt = "Preview" self.preview_button.set_label(ptxt)
def scan_image(map, block, height): foreground = pdb.gimp_context_get_foreground() pdb.gimp_context_set_sample_threshold(0.0) for i in xrange(0, 150): pdb.gimp_image_select_color(map.image, 2, map, map_palette[i][0]) pdb.gimp_context_set_foreground(map_palette[(i/3)*3+1][0]) if pdb.gimp_selection_is_empty(map.image) == True: continue #time.sleep(1) pdb.gimp_edit_bucket_fill(block, 0, 0, 100, 0, False, 0, 0) #time.sleep(3) if i % 3 == 0: pdb.gimp_context_set_foreground(map_palette[21][0]) if i % 3 == 1: pdb.gimp_context_set_foreground(map_palette[31][0]) if i % 3 == 2: pdb.gimp_context_set_foreground(map_palette[83][0]) pdb.gimp_edit_bucket_fill(height, 0, 0, 100, 0, False, 0, 0) gimp.displays_flush() pdb.gimp_context_set_foreground(foreground) pdb.gimp_selection_none(map.image)
def do_stuff(img, layer, mapswide, mapstall) : setup_palette() gimp.progress_init("Minecraft Mapifying " + layer.name + "...") # Disable Undo as we are creating a new window pdb.gimp_image_undo_disable(img) new_img = pdb.gimp_image_duplicate(img) gimp.Display(new_img) gimp.displays_flush() pdb.gimp_image_undo_disable(new_img) # Calculate the height and width of the new image img_ratio = float(layer.width) / float(layer.height) map_ratio = float(mapswide) / float(mapstall) offset_x = 0 offset_y = 0 width = 0 height = 0 # If the aspect ratio of the original image is greater than the aspect ratio of the maps, # then the original image needs padding above and below to fit the maps if img_ratio > map_ratio: width = mapswide * 128 height = int(float(width) / img_ratio) offset_y = ((map_ratio * 128) - height) / 2 # otherwise padding is needed to the left and right else: height = mapstall * 128 width = int(img_ratio * float(height)) offset_x = ((map_ratio * 128) - width) / 2 # Resize the image to the fit the maps requested pdb.gimp_context_set_interpolation(INTERPOLATION_CUBIC) pdb.gimp_image_scale(new_img, width, height) new_img.resize(mapswide * 128, mapstall * 128, int(offset_x), int(offset_y)) # Create a new background layer, fill it with the background color, and flatten the image to create the padding new_img.add_layer(new_img.active_layer.copy(), 1) new_img.layers[1].resize(mapswide * 128, mapstall * 128, int(offset_x), int(offset_y)) new_img.layers[1].fill(BACKGROUND_FILL) new_img.flatten() new_img.active_layer.name = layer.name # Turn the image into the map palette pdb.gimp_image_convert_indexed(new_img, CONVERT_DITHER_FS_LOWBLEED, CONVERT_PALETTE_CUSTOM, 0, False, True, "Minecraft Map In Order") gimp.displays_flush() # Create 2 duplicate layers as they will be used in outputing the build details new_img.add_layer(new_img.layers[0].copy(), 1) new_img.add_layer(new_img.layers[0].copy(), 2) new_img.layers[0].name = layer.name + " [Map]" new_img.layers[1].name = layer.name + " [Types]" new_img.layers[2].name = layer.name + " [Heights]" scan_image(new_img.layers[0], new_img.layers[1], new_img.layers[2]) # Enable undo again pdb.gimp_image_undo_enable(img) pdb.gimp_image_undo_enable(new_img)
def contact_sheet(file_type, location, all_subdirs, inc_filename, inc_extension, contact_name, contact_type, contact_location, contact_size, dpi, orient, num_col, num_rows, PageBorderLR, PageBorderTB, mmTHUMB_MARGIN, mmFONT_SIZE, Dump_Filename_list, Sorted_Images, Print_Contactsheet): # pdb.gimp_message (location) if os.path.exists(u'' + location): # pdb.gimp_message ("continuing1") # do nothing just set a variable xblot = 1 else: pdb.gimp_message(_("%s doesn't exist") % (location)) return if os.path.exists(u'' + contact_location): # pdb.gimp_message ("continuing2") # do nothing just set a variable xblot = 1 else: pdb.gimp_message(_("%s doesn't exist") % (contact_location)) return #collect 'all' images in the choosen directory and subdirs images = get_images(file_type, location, all_subdirs, Dump_Filename_list, Sorted_Images) num_images = len(images) #calculate number of images #if necessary make a txt file with image name and image directory if (Dump_Filename_list == True): Make_DirFile_List(images, contact_location, contact_name) #make a new drawing canvas of the correct size width, height = CalcPaperSize(contact_size, dpi) #dimensions in px #calculate the required size for the thumbs based on the number of images #per row. Sizes are in px and floored with maximum error of one px LEFT_PAGE_BORDER = (PageBorderLR / 25.4) * dpi RIGHT_PAGE_BORDER = (PageBorderLR / 25.4) * dpi BOTTOM_PAGE_BORDER = (PageBorderTB / 25.4) * dpi THUMB_MARGIN = (mmTHUMB_MARGIN / 25.4) * dpi FONT_SIZE = (mmFONT_SIZE / 25.4) * dpi TOP_PAGE_BORDER = (PageBorderTB / 25.4) * dpi + FONT_SIZE #include sheet .. of .. #number of rows is limited so is ThumbsPerSheet #Thumb sizes are in px, based on dpi setting if (orient == "port"): Thumb_width = ((width - LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER) / num_col) - 2 * THUMB_MARGIN if (inc_filename == True): UsableRows = floor( (height - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER) / (Thumb_width + FONT_SIZE + 2 * THUMB_MARGIN)) else: UsableRows = floor( (height - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER) / (Thumb_width + 2 * THUMB_MARGIN)) else: Thumb_width = ((height - LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER) / num_col) - 2 * THUMB_MARGIN if (inc_filename == True): UsableRows = floor((width - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER) / (Thumb_width + FONT_SIZE + 2 * THUMB_MARGIN)) else: UsableRows = floor((width - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER) / (Thumb_width + 2 * THUMB_MARGIN)) Thumb_height = Thumb_width #Number of chosen rows can never be bigger then usable rows if (num_rows > UsableRows): num_rows = UsableRows ThumbsPerSheet = int(num_col * num_rows) #added 'int' for python v2.6 img_no = 1 for sheetcount in range(int(ceil(num_images / float(ThumbsPerSheet)))): if (orient == "land"): sheetimg = gimp.Image(height, width, RGB) bklayer = gimp.Layer(sheetimg, "Background", height, width, RGB_IMAGE, 100, LAYER_MODE_NORMAL) else: sheetimg = gimp.Image(width, height, RGB) bklayer = gimp.Layer(sheetimg, "Background", width, height, RGB_IMAGE, 100, LAYER_MODE_NORMAL) sheetimg.disable_undo() sheetimg.add_layer(bklayer, 0) #set the image resolution sheetimg.resolution = (float(dpi), float(dpi)) #now calculate sizes; printable sheet dimensions are given #in px based on the dpi setting Canvas_width = sheetimg.width - LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER Canvas_height = sheetimg.height - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER #print ("Canvas width %d height %d" % ( Canvas_width,Canvas_height)) #Log(str(sheetimg.resolution)) #now fill with white, How to fill with a other color????? bklayer.fill(FILL_WHITE) # gimp.set_background(bk_color) # gimp-bklayer-fill(bklayer, IMAGE-FILL-BG) # Log (str(bk_color)) # bklayer.fill(bk_color) # Log(str(gimp.get_background())) bklayer.flush() sheetdsp = gimp.Display(sheetimg) #print "sheet display" + str(sheetdsp) gimp.displays_flush() txtw, CalcTextHeight, txte, txtd = pdb.gimp_text_get_extents_fontname( _("Sheet %03d of %03d") % (sheetcount + 1, int(ceil(num_images / float(ThumbsPerSheet)))), FONT_SIZE, PIXELS, "Arial") ## txtfloat = pdb.gimp_text_fontname(sheetimg, sheetimg.active_layer, #only for me ## LEFT_PAGE_BORDER, TOP_PAGE_BORDER-CalcTextHeight, ## _("Sheet %03d of %03d"), ## contactsheet designed by R, Gilham (za) and E. Sullock Enzlin (nl)" ## % (sheetcount+1,int(ceil(num_images/float(ThumbsPerSheet)))), ## -1, False, FONT_SIZE, PIXELS, "Arial") txtfloat = pdb.gimp_text_fontname( sheetimg, sheetimg.active_layer, LEFT_PAGE_BORDER, TOP_PAGE_BORDER - CalcTextHeight, _("Sheet %03d of %03d") % (sheetcount + 1, int(ceil(num_images / float(ThumbsPerSheet)))), -1, False, FONT_SIZE, PIXELS, "Arial") pdb.gimp_floating_sel_anchor(txtfloat) CalcTextHeight = 0 txtw, txth, txte, txtd = (0, 0, 0, 0) if (inc_filename == True): txtw, CalcTextHeight, txte, txtd = pdb.gimp_text_get_extents_fontname( images[0]['base_name'], FONT_SIZE, PIXELS, "Arial") #print "CalcText Height %d " %(CalcTextHeight) files = images[sheetcount * ThumbsPerSheet:(sheetcount + 1) * ThumbsPerSheet] #now for each of the image files generate a thumbnail rcount = 0 ccount = 0 #generate thumb for file in files: thumbimg, x_size, y_size, valid_image = generate_thumb( file['image_file'], Thumb_width, Thumb_height) if valid_image == False: continue #next image cpy = pdb.gimp_edit_copy(thumbimg.active_layer) #center image within its minipage if (x_size > y_size): #landscape image, center vertical y_offset = (Thumb_width - y_size) / 2 x_offset = 0 else: #portrait image, center horizontal x_offset = (Thumb_height - x_size) / 2 y_offset = 0 gimp.delete(thumbimg) #now paste the new thumb into contact sheet newselect = pdb.gimp_edit_paste(sheetimg.active_layer, True) #print str(newselect) #print str(newselect.offsets) #positition in top left corner newselect.translate(-newselect.offsets[0], -newselect.offsets[1]) #now position in correct position, modified with x- and y-offset xpos = LEFT_PAGE_BORDER + ccount * ( Thumb_width + (2 * THUMB_MARGIN)) + THUMB_MARGIN + x_offset ypos = TOP_PAGE_BORDER + rcount * ( Thumb_height + (2 * THUMB_MARGIN) + CalcTextHeight) + THUMB_MARGIN + y_offset xpos = int( xpos ) #changed to int: on ubuntu type error integer expected got float. ypos = int(ypos) newselect.translate(xpos, ypos) pdb.gimp_floating_sel_anchor(newselect) if (inc_filename == True): if (inc_extension == True): ThumbName = file['base_name'] + file['extension'] else: ThumbName = file['base_name'] Size, txtwidth = CalcFontSize(ThumbName, "Arial", FONT_SIZE, CalcTextHeight, Thumb_width) #calculate text position, round the center of the image txt_xpos = xpos + (Thumb_width - txtwidth) / 2 - x_offset txt_ypos = ypos + Thumb_height + THUMB_MARGIN - y_offset txtfloat = pdb.gimp_text_fontname(sheetimg, sheetimg.active_layer, txt_xpos, txt_ypos, ThumbName, -1, False, Size, PIXELS, "Arial") pdb.gimp_floating_sel_anchor(txtfloat) ccount = ccount + 1 if (ccount >= num_col): ccount = 0 rcount = rcount + 1 gimp.displays_flush() #save contactsheet contact_filename = contact_name + "_%03d" % (sheetcount + 1) + contact_type contact_full_filename = os.path.join(contact_location, contact_filename) #print "File to save " + contact_full_filename if (contact_type == ".jpg"): save_jpeg(sheetimg, contact_full_filename, "") else: save_png(sheetimg, pdb.gimp_image_get_active_drawable(sheetimg), contact_full_filename, False) if (Print_Contactsheet == True): pdb.file_print_gtk(sheetimg) gimp.delete(sheetimg) pdb.gimp_display_delete(sheetdsp)
def LBP(self): width = self.drawable.width height = self.drawable.height #bpp = self.drawable.bpp rad = self.radius #debugging messages #print("Velikost obrazku: " + str(width) + "x" + str(height)) #create new output layer self.layer = gimp.Layer(self.image, "LBP", width, height, GRAY_IMAGE, 100, NORMAL_MODE) #add layer into image self.image.add_layer(self.layer, 0) #region for output dest_rgn = self.layer.get_pixel_rgn(0, 0, width, height, True, True) #custom array for results drawTo = array.array("B") #get image data (region) and convert to array imageArr = self.drawable.get_pixel_rgn(0, 0, width, height, False, False) imageArr_pixels = array.array("B", imageArr[0:width, 0:height]) #convert 1D array to 2D array tmp = np.reshape(imageArr_pixels, (-1, width)) #create array with mirrored border dataBorder = np.pad(array=tmp, pad_width=rad, mode='symmetric') gimp.progress_init("LBP") for x in range(rad, height + rad): for y in range(rad, width + rad): binaryNum = [] #get exactly eight pixels in radius from pixel [x,y] src_pixels = dataBorder[x - rad:x + 1 + rad:rad, y - rad:y + 1 + rad:rad] src_pixels = src_pixels.ravel() #make 2D array 1D #get value of the center pixel [x,y] center = src_pixels[4] #sequence of indexes indexesNeeded = [0, 1, 2, 5, 8, 7, 6, 3] for i in indexesNeeded: if src_pixels[i] > center: binaryNum.append(0) else: binaryNum.append(1) #"count" LBP for pixel st = ''.join(format(str(x)) for x in binaryNum) res = int(st, 2) drawTo.append(res) gimp.progress_update(float(x + 1) / height) #result dest_rgn[0:width, 0:height] = drawTo.tostring() #apply changes self.layer.flush() #apply selection mask self.layer.merge_shadow(True) #refresh self.layer.update(0, 0, width, height) #refresh gimp.displays_flush()
def removePreviews(self): if self.layer_exists(self.previewLayer): self.img.remove_layer(self.previewLayer) self.previewLayer = None gimp.displays_flush()
def gaussian_blur_main(image, drawable): (bx1, by1, bx2, by2) = drawable.mask_bounds pdb.gimp_image_undo_group_start(image) #dummy funkce (vubec nic nedela, slouzi pro nastaveni undo) pdb.gimp_levels(drawable, HISTOGRAM_VALUE, 0, 255, 1.0, 0, 255) bw = bx2 - bx1 bh = by2 - by1 bpp = drawable.bpp #nacteni pixlu src_rgn = drawable.get_pixel_rgn(0, 0, image.width, image.height) src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) np_array = np.array(src_pixels).reshape(bh, bw, bpp) # definice filteru filter = np.array([ [1. / 16, 2. / 16, 1. / 16], [2. / 16, 4. / 16, 2. / 16], [1. / 16, 2. / 16, 1. / 16], ]) # aplikace filteru @jit(nopython=True, cache=True) def apply_filter_body(data, mask, output): data_w, data_h = data.shape for y in range(1, data_h - 1): for x in range(1, data_w - 1): cut = data[x - 1:x + 2, y - 1:y + 2] output[x, y] = (cut * mask).sum() def apply_filter(data, mask, output): data_w, data_h = data.shape cut = np.array([ data[0, 0], data[0, 0], data[0, 1], data[0, 0], data[0, 0], data[0, 1], data[1, 0], data[1, 0], data[1, 1] ]).reshape(3, 3) output[0, 0] = (cut * mask).sum() cut = np.array([ data[0, data_h - 2], data[0, data_h - 1], data[0, data_h - 1], data[0, data_h - 2], data[0, data_h - 1], data[0, data_h - 1], data[1, data_h - 2], data[1, data_h - 1], data[1, data_h - 1] ]).reshape(3, 3) output[0, data_h - 1] = (cut * mask).sum() cut = np.array([ data[data_w - 2, 0], data[data_w - 2, 0], data[data_w - 2, 1], data[data_w - 1, 0], data[data_w - 1, 0], data[data_w - 1, 1], data[data_w - 1, 0], data[data_w - 1, 0], data[data_w - 1, 1] ]).reshape(3, 3) output[data_w - 1, 0] = (cut * mask).sum() cut = np.array([ data[data_w - 2, data_h - 2], data[data_w - 2, data_h - 1], data[data_w - 2, data_h - 1], data[data_w - 1, data_h - 2], data[data_w - 1, data_h - 1], data[data_w - 1, data_h - 1], data[data_w - 1, data_h - 2], data[data_w - 1, data_h - 1], data[data_w - 1, data_h - 1] ]).reshape(3, 3) output[data_w - 1, data_h - 1] = (cut * mask).sum() for y in range(1, data_h - 1): cut = data[[0, 0, 1], y - 1:y + 2] output[0, y] = (cut * mask).sum() cut = data[[data_w - 2, data_w - 1, data_w - 1], y - 1:y + 2] output[data_w - 1, y] = (cut * mask).sum() for x in range(1, data_w - 1): cut = data[x - 1:x + 2, [0, 0, 1]] output[x, 0] = (cut * mask).sum() cut = data[x - 1:x + 2, [data_h - 2, data_h - 1, data_h - 1]] output[x, data_h - 1] = (cut * mask).sum() apply_filter_body(data, mask, output) out = np.zeros([bh, bw, bpp], dtype=int) for canal in range(bpp): apply_filter(np_array[:, :, canal], filter, out[:, :, canal]) out = np.minimum(np.maximum(out, 0), 255) out = out.reshape(bw * bh * bpp, 1) tmp_array = array.array('B', out) src_rgn[bx1:bx2, by1:by2] = tmp_array.tostring() drawable.flush() drawable.update(0, 0, image.width, image.height) gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def remap_hue(self): #input can be RGB or RGBA bpp = self.drawable.bpp (bx1, by1, bx2, by2) = self.drawable.mask_bounds bw = bx2 - bx1 bh = by2 - by1 #input layer offset (ox, oy) = self.drawable.offsets src_rgn = self.drawable.get_pixel_rgn(bx1, by1, bw, bh, False, False) #all the input pixels in one huge array #src_rgn[...] returns a packed byte array as a string #we unpack this string using python array src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) #delete existing preview layer self.layer_destroy() #create new output layer self.layer = gimp.Layer(self.image, "Hue map", bw, bh, RGBA_IMAGE, 100, NORMAL_MODE) #set correct position self.layer.set_offsets(bx1 + ox, by1 + oy) dest_rgn = self.layer.get_pixel_rgn(0, 0, bw, bh, True, True) #all the output pixels dest_pixels = array.array("B", dest_rgn[0:bw, 0:bh]) #output is always RGBA dest_bpp = 4 #add layer into image self.image.add_layer(self.layer, 0) #for 8bit RGB, the hue resolution is 6*256 = 1536 #sampling in lower resolution (like 360°) would result in color loss #we pre-sample the gradient instead of sampling it on each pixel #it results in better performance on larger selections (> 39x39 px) num_samples = 6 * 256 hue_samples = pdb.gimp_gradient_get_uniform_samples( self.gradient_button.get_gradient(), num_samples + 1, False)[1] hues = [None] * num_samples for i in range(0, num_samples): #convert rgb into hue sample_rgb = gimpcolor.RGB(hue_samples[i * 4 + 0], hue_samples[i * 4 + 1], hue_samples[i * 4 + 2], hue_samples[i * 4 + 3]) hues[i] = sample_rgb.to_hsv().h #start a progress bar gimp.progress_init("Hue map") for y in range(0, bh): for x in range(0, bw): pos = (x + bw * y) * bpp #read a pixel as a 3 or 4 byte array c_array = src_pixels[pos:(pos + bpp)] #create a RGB struct, if there is no alpha, set it to 100% c_rgb = gimpcolor.RGB(c_array[0], c_array[1], c_array[2], c_array[3] if bpp == 4 else 255) #RGB -> HSV c_hsv = c_rgb.to_hsv() #calculate index into hue replacement array hue_index = int(round(c_hsv.h * num_samples)) #replace hue c_hsv.h = hues[hue_index] #HSV -> RGB c_rgb = c_hsv.to_rgb() #RGB -> byte array c_array[0:dest_bpp] = array.array("B", c_rgb[0:dest_bpp]) dest_pos = (x + bw * y) * dest_bpp #write a pixel into the output array dest_pixels[dest_pos:(dest_pos + dest_bpp)] = c_array #update the progress bar gimp.progress_update(float(y + 1) / bh) #write the output pixel array into the output layer dest_rgn[0:bw, 0:bh] = dest_pixels.tostring() #apply changes self.layer.flush() #apply selection mask self.layer.merge_shadow(True) #refresh self.layer.update(0, 0, bw, bh) #refresh gimp.displays_flush()
def color_filter_main(image, drawable, color_org=(1.0, 1.0, 1.0), level=10, filterer_by=0): (bx1, by1, bx2, by2) = drawable.mask_bounds pdb.gimp_image_undo_group_start(image) gimp.progress_update(0) #dummy funkce (vubec nic nedela, slouzi pro nastaveni undo) pdb.gimp_levels(drawable, HISTOGRAM_VALUE, 0, 255, 1.0, 0, 255) bw = bx2 - bx1 bh = by2 - by1 bpp = drawable.bpp #nacteni pixlu src_rgn = drawable.get_pixel_rgn(0, 0, image.width, image.height) src_pixels = array.array("B", src_rgn[bx1:bx2, by1:by2]) np_array = np.array(src_pixels).reshape(bh * bw, bpp) @jit def apply_by_HSV(np_array, bh, bw, level, color_org): H, S, V = colorsys.rgb_to_hsv(color_org[0] / 255., color_org[1] / 255., color_org[2] / 255.) H = int(H * 360) size = bh * bw for i in range(size): tmp_H, tmp_S, tmp_V = colorsys.rgb_to_hsv(np_array[i, 0] / 255., np_array[i, 1] / 255., np_array[i, 2] / 255.) tmp_H = int(tmp_H * 360) diff_H = min(abs(H - tmp_H), 360 - abs(H - tmp_H)) if (diff_H > level): tmp_grey = np_array[i, 0] * .299 + np_array[ i, 1] * .587 + np_array[i, 2] * .114 np_array[i, 0] = tmp_grey np_array[i, 1] = tmp_grey np_array[i, 2] = tmp_grey gimp.progress_update(float(i) / size) @jit def apply_by_RGB(np_array, bh, bw, level, color_org): size = bh * bw for i in range(size): if (abs(np_array[i, 0] - color_org[0]) > level or abs(np_array[i, 1] - color_org[1]) > level or abs(np_array[i, 2] - color_org[2]) > level): tmp_grey = np_array[i, 0] * .299 + np_array[ i, 1] * .587 + np_array[i, 2] * .114 np_array[i, 0] = tmp_grey np_array[i, 1] = tmp_grey np_array[i, 2] = tmp_grey gimp.progress_update(float(i) / size) if (filterer_by): apply_by_RGB(np_array, bh, bw, level, color_org) else: apply_by_HSV(np_array, bh, bw, level, color_org) np_array = np_array.reshape(bw * bh * bpp, 1) tmp_array = array.array('B', np_array) src_rgn[bx1:bx2, by1:by2] = tmp_array.tostring() drawable.flush() drawable.update(0, 0, image.width, image.height) gimp.displays_flush() pdb.gimp_image_undo_group_end(image)
def Contact_Sheet(file_type, location, all_subdirs, inc_filename, inc_extension, contact_name, contact_type, contact_location, contact_size, dpi, orient, num_col, num_rows, PageBorderLR, PageBorderTB, mmTHUMB_MARGIN, mmFONT_SIZE, Dump_Filename_list, Sorted_Images, Print_Contactsheet): #collect 'all' images in the choosen directory and subdirs images = get_images(file_type, location, all_subdirs, Dump_Filename_list, Sorted_Images) num_images = len(images) #calculate number of images #if necessary make a txt file with image name and image directory if (Dump_Filename_list == True): Make_DirFile_List(images, contact_location, contact_name) #make a new drawing canvas of the correct size width,height = CalcPaperSize(contact_size, dpi) #dimensions in px #calculate the required size for the thumbs based on the number of images #per row. Sizes are in px and floored with maximum error of one px LEFT_PAGE_BORDER = (PageBorderLR/25.4)*dpi RIGHT_PAGE_BORDER = (PageBorderLR/25.4)*dpi BOTTOM_PAGE_BORDER = (PageBorderTB/25.4)*dpi THUMB_MARGIN = (mmTHUMB_MARGIN/25.4)*dpi FONT_SIZE = (mmFONT_SIZE/25.4)*dpi TOP_PAGE_BORDER = (PageBorderTB/25.4)*dpi + FONT_SIZE #include sheet .. of .. #number of rows is limited so is ThumbsPerSheet #Thumb sizes are in px, based on dpi setting if (orient=="port"): Thumb_width = ((width- LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER)/num_col)- 2*THUMB_MARGIN if (inc_filename == True): UsableRows = floor((height- TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER)/ (Thumb_width + FONT_SIZE + 2*THUMB_MARGIN)) else: UsableRows = floor((height- TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER)/ (Thumb_width + 2*THUMB_MARGIN)) else: Thumb_width = ((height- LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER)/num_col)- 2*THUMB_MARGIN if (inc_filename == True): UsableRows = floor((width- TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER)/ (Thumb_width + FONT_SIZE + 2*THUMB_MARGIN)) else: UsableRows = floor((width- TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER)/ (Thumb_width + 2*THUMB_MARGIN)) Thumb_height = Thumb_width #Number of chosen rows can never be bigger then usable rows if (num_rows > UsableRows): num_rows = UsableRows ThumbsPerSheet = int(num_col*num_rows) #added 'int' for python v2.6 img_no = 1 for sheetcount in range(int(ceil(num_images/float(ThumbsPerSheet)))): if (orient=="land"): sheetimg = gimp.Image(height,width,RGB) bklayer = gimp.Layer(sheetimg,"Background",height,width, RGB_IMAGE,100,NORMAL_MODE) else: sheetimg = gimp.Image(width,height,RGB) bklayer = gimp.Layer(sheetimg,"Background",width,height, RGB_IMAGE,100,NORMAL_MODE) sheetimg.disable_undo() sheetimg.add_layer(bklayer,0) #set the image resolution sheetimg.resolution = (float(dpi), float(dpi)) #now calculate sizes; printable sheet dimensions are given #in px based on the dpi setting Canvas_width = sheetimg.width - LEFT_PAGE_BORDER - RIGHT_PAGE_BORDER Canvas_height = sheetimg.height - TOP_PAGE_BORDER - BOTTOM_PAGE_BORDER #print ("Canvas width %d height %d" % ( Canvas_width,Canvas_height)) #Log(str(sheetimg.resolution)) #now fill with white, How to fill with a other color????? bklayer.fill(WHITE_FILL) # gimp.set_background(bk_color) # gimp-bklayer-fill(bklayer, BG-IMAGE-FILL) # Log (str(bk_color)) # bklayer.fill(bk_color) # Log(str(gimp.get_background())) bklayer.flush() sheetdsp = gimp.Display(sheetimg) #print "sheet display" + str(sheetdsp) gimp.displays_flush() txtw,CalcTextHeight,txte,txtd = pdb.gimp_text_get_extents_fontname( _("Sheet %03d of %03d") % (sheetcount+1,int(ceil(num_images/float(ThumbsPerSheet)))), FONT_SIZE,PIXELS,"Arial") ## txtfloat = pdb.gimp_text_fontname(sheetimg, sheetimg.active_layer, #only for me ## LEFT_PAGE_BORDER, TOP_PAGE_BORDER-CalcTextHeight, ## _("Sheet %03d of %03d"), ## contactsheet designed by R, Gilham (za) and E. Sullock Enzlin (nl)" ## % (sheetcount+1,int(ceil(num_images/float(ThumbsPerSheet)))), ## -1, False, FONT_SIZE, PIXELS, "Arial") txtfloat = pdb.gimp_text_fontname(sheetimg, sheetimg.active_layer, LEFT_PAGE_BORDER, TOP_PAGE_BORDER-CalcTextHeight, _("Sheet %03d of %03d") % (sheetcount+1,int(ceil(num_images/float(ThumbsPerSheet)))), -1, False, FONT_SIZE, PIXELS, "Arial") pdb.gimp_floating_sel_anchor(txtfloat) CalcTextHeight =0 txtw,txth,txte,txtd = (0,0,0,0) if (inc_filename == True): txtw,CalcTextHeight,txte,txtd = pdb.gimp_text_get_extents_fontname(images[0]['base_name'], FONT_SIZE,PIXELS,"Arial") #print "CalcText Height %d " %(CalcTextHeight) files = images[sheetcount*ThumbsPerSheet:(sheetcount+1)*ThumbsPerSheet] #now for each of the image files generate a thumbnail rcount = 0 ccount = 0 #generate thumb for file in files: thumbimg,x_size,y_size = generate_thumb(file['image_file'],Thumb_width,Thumb_height) cpy = pdb.gimp_edit_copy(thumbimg.active_layer) #center image within its minipage if (x_size>y_size): #landscape image, center vertical y_offset = (Thumb_width - y_size)/2 x_offset = 0 else: #portrait image, center horizontal x_offset = (Thumb_height - x_size)/2 y_offset = 0 gimp.delete(thumbimg) #now paste the new thumb into contact sheet newselect = pdb.gimp_edit_paste(sheetimg.active_layer,True) #print str(newselect) #print str(newselect.offsets) #positition in top left corner newselect.translate(-newselect.offsets[0],-newselect.offsets[1]) #now position in correct position, modified with x- and y-offset xpos = LEFT_PAGE_BORDER + ccount * (Thumb_width + (2 * THUMB_MARGIN))+ THUMB_MARGIN + x_offset ypos = TOP_PAGE_BORDER + rcount * (Thumb_height + (2 * THUMB_MARGIN) + CalcTextHeight) + THUMB_MARGIN + y_offset newselect.translate(xpos,ypos) pdb.gimp_floating_sel_anchor(newselect) if (inc_filename == True): if (inc_extension == True): ThumbName = file['base_name'] + file['extension'] else: ThumbName = file['base_name'] Size,txtwidth = CalcFontSize(ThumbName,"Arial",FONT_SIZE,CalcTextHeight,Thumb_width) #calculate text position, round the center of the image txt_xpos = xpos + (Thumb_width - txtwidth)/2 - x_offset txt_ypos = ypos+Thumb_height+THUMB_MARGIN-y_offset txtfloat = pdb.gimp_text_fontname(sheetimg, sheetimg.active_layer, txt_xpos, txt_ypos, ThumbName,-1, False, Size, PIXELS, "Arial") pdb.gimp_floating_sel_anchor(txtfloat) ccount = ccount + 1 if (ccount>= num_col): ccount = 0 rcount = rcount + 1 gimp.displays_flush() #save contactsheet contact_filename = contact_name + "_%03d" % (sheetcount) + contact_type contact_full_filename = os.path.join(contact_location, contact_filename) #print "File to save " + contact_full_filename if (contact_type == ".jpg"): save_jpeg(sheetimg,contact_full_filename,"") else: save_png(sheetimg,pdb.gimp_image_get_active_drawable(sheetimg),contact_full_filename,False) if (Print_Contactsheet == True): pdb.file_print_gtk(sheetimg) gimp.delete(sheetimg) pdb.gimp_display_delete(sheetdsp)