Пример #1
0
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)
Пример #2
0
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()
Пример #3
0
    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
Пример #4
0
 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()
Пример #5
0
    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()
Пример #6
0
 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()
Пример #7
0
 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()
Пример #8
0
	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
Пример #9
0
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)
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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)
Пример #14
0
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)
Пример #15
0
    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)
Пример #16
0
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)
Пример #17
0
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)
Пример #19
0
    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()
Пример #21
0
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)
Пример #22
0
    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()
Пример #23
0
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)
Пример #24
0
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)