Posts: 4
Threads: 1
Joined: Mar 2024
Reputation:
0
Operating system(s):
- Windows Vista or 7, 8, 10 (64-bit)
Gimp version: 2.10
03-28-2024, 11:55 AM
Hello Guys,
I am currently setting up an online shop where i have mockups of digital art.
I am relatively new to gimp but i am fairly trusted with scripting/coding.
I already managed to write a plugin which rescales a file to several formats.
Now i want to fit an image into the empty mockups. Since i dont want to waste hours doing that manually, i want to automate this.
Example:
1. I have my blank Mockup Image
2. I have my image which does not yet fit into the mockup space
3. Now i have to insert the image into the mockup image
4. Now i have to rescale and move the image to the mockup space and make it blend in perfectly
5. Save the mockup with the inserted image
I want to automate this procedure so i can chose a set of images and then they get inserted into different mockups automatically.
Is there any function/plugin like this?
If no is it possible to create a fu-python plugin myself to achieve this?
Basically the mockup does not change. The empty space will always have the same position and size. I just have to fit the image to it.
Thanks in advance if anyone can help me!
Best Regards
Daniel
Posts: 6,386
Threads: 278
Joined: Oct 2016
Reputation:
566
Operating system(s):
Gimp version: 3.00RC1
(03-28-2024, 11:55 AM)kaiserart Wrote: Is there any function/plugin like this?
If no is it possible to create a fu-python plugin myself to achieve this?
Basically the mockup does not change. The empty space will always have the same position and size. I just have to fit the image to it.
- None I know of
- Yes
- You probably want to keep the mockup as an XCF mark the empty space with a layer at the right size/position
You can also do this with ImageMagick compose but you have to find an external way to remember the size/position of the empty space.
Posts: 4
Threads: 1
Joined: Mar 2024
Reputation:
0
Operating system(s):
- Windows Vista or 7, 8, 10 (64-bit)
Gimp version: 2.10
03-28-2024, 08:14 PM
(This post was last modified: 03-28-2024, 08:15 PM by kaiserart.)
(03-28-2024, 12:06 PM)Ofnuts Wrote: (03-28-2024, 11:55 AM)kaiserart Wrote: Is there any function/plugin like this?
If no is it possible to create a fu-python plugin myself to achieve this?
Basically the mockup does not change. The empty space will always have the same position and size. I just have to fit the image to it.
- None I know of
- Yes
- You probably want to keep the mockup as an XCF mark the empty space with a layer at the right size/position
You can also do this with ImageMagick compose but you have to find an external way to remember the size/position of the empty space.
Thanks for your reply. I managed to create a plugin for myself which iterates through every image in a folder and then through every mockup in a folder.
Then scales and positions the image according to the mockup and create a blurred shadow around it to make it more seamless.
Still i have one more question.
When the script finishes actually successfully it says in a GIMP Message:
"Unable to run GimpPdbProgress callback. The corresponding plug-in may have crashed."
Here is my Script (it is rather rudimental, also with absolute paths):
Code:
from gimpfu import *
import os
def set_stroke_params():
# Set opacity to 100%
pdb.gimp_context_set_opacity(100)
# Set paint mode to NORMAL
pdb.gimp_context_set_paint_mode(0) # NORMAL mode
# Set paint method to GRAYA (this is the default)
pdb.gimp_context_set_paint_method("gimp-paintbrush") # GRAYA method
# Set stroke method to PAINT
pdb.gimp_context_set_stroke_method("0") # PAINT method
# Set foreground color to black
pdb.gimp_context_set_foreground((0, 0, 0)) # Black color
# Set active brush (assuming you've already defined the brush)
brush_name = "Circle (01)"
pdb.gimp_context_set_brush(brush_name)
# Set line width to 10
pdb.gimp_context_set_line_width(6)
# Enable antialiasing
pdb.gimp_context_set_antialias(True)
def create_outline_layer(mockup_image, scaled_image):
# Create a new layer filled with transparent color
outline_layer = pdb.gimp_layer_new(mockup_image, scaled_image.width, scaled_image.height, RGBA_IMAGE, "Outline", 100, NORMAL_MODE)
pdb.gimp_image_insert_layer(mockup_image, outline_layer, None, 0)
return outline_layer
def mockup_scaleandmove_horizontal(image, drawable):
mockups = ["WoodFrame_1.jpg", "BlackBorder_1.jpg", "Gaming_1.jpg", "Gaming_2.jpg", "LivingRoom_1.jpg"]
pos_x = [295, 113, 212, 303, 163]
pos_y = [611, 236, 112, 171, 115]
scale_x = [1461, 801, 492, 436, 699]
scale_y = [850, 540, 290, 270, 435]
mockup_folder_path = "C:/Users/Daniel Kunz/Desktop/MidJourney/Mockups/Horizontal/Frontal"
original_folder_path = "C:/Users/Daniel Kunz/Desktop/MidJourney/NewArt"
mockup_image_path = ""
original_image_path = ""
# Iterate through each new file
for filename_original in os.listdir(original_folder_path):
# Check if it's a file
if os.path.isfile(os.path.join(original_folder_path, filename_original)):
original_image_path = original_folder_path + "/" + filename_original
# Iterate through each mockup
for index, mockup in enumerate(mockups):
# Iterate through each file in the folder
for filename_mockup in os.listdir(mockup_folder_path):
# Check if it's a file
if os.path.isfile(os.path.join(mockup_folder_path, filename_mockup)):
if filename_mockup == mockup:
# Set Mockup Image Path
mockup_image_path = mockup_folder_path + "/" + filename_mockup
# Load the Mockup Image
mockup_image = pdb.gimp_file_load(mockup_image_path, mockup_image_path)
# Load the Original Image
original_image = pdb.gimp_file_load(original_image_path, original_image_path)
# Resize the original image to fit the mockup
pdb.gimp_image_scale(original_image, scale_x[index], scale_y[index])
# Create a new layer in the mockup image
layer = pdb.gimp_layer_new_from_drawable(original_image.active_drawable, mockup_image)
# Add the layer to the mockup image
pdb.gimp_image_insert_layer(mockup_image, layer, None, 0)
# Move the layer to the fixed position
pdb.gimp_layer_translate(layer, pos_x[index], pos_y[index])
# Create a new layer with only the outline of the selection
outline_layer = create_outline_layer(mockup_image, original_image)
# Move the layer to the fixed position
pdb.gimp_layer_translate(outline_layer, pos_x[index], pos_y[index])
# Select the outline
pdb.gimp_selection_all(outline_layer.image)
# Stroke the selection to draw a line around it
set_stroke_params()
pdb.gimp_drawable_edit_stroke_selection(outline_layer)
# Apply Gaussian blur to the outline layer
pdb.plug_in_gauss(mockup_image, outline_layer, 10, 10, 1)
# Merge the blurred stroke layer with the original layer
# Merge visible layers
merged_layer = pdb.gimp_image_merge_visible_layers(mockup_image, CLIP_TO_IMAGE)
#pdb.gimp_image_merge_down(mockup_image, outline_layer, EXPAND_AS_NECESSARY)
# Save the merged image
output_filename = filename_original[:-4] + filename_mockup + ".jpg"
output_foldername = "{}".format(filename_original[:-4])
output_folder = "C:/Users/Daniel Kunz/Desktop/MidJourney/Images/NewMockups/" + output_foldername
# Check if the directory already exists
if not os.path.exists(output_folder):
# If it doesn't exist, create the directory
os.makedirs(output_folder)
filename = os.path.join(output_folder, output_filename[:-4])
pdb.gimp_file_save(mockup_image, merged_layer, filename, filename)
# Close the images to conserve memory
pdb.gimp_image_delete(mockup_image)
pdb.gimp_image_delete(original_image)
# Notify user
gimp.message("Images rescaled, stroke painted, and saved successfully!")
register(
"python_fu_mockup_scaleandmove_horizontal",
"Rescale, paint stroke, and save images",
"Rescale the input image into 5 different sizes, paint a stroke around the scaled and moved original image, and save them with DPI set to 300.",
"Daniel Kunz",
"Daniel Kunz",
"2024",
"<Image>/Filters/Mockup ScaleAndMove Horizontal",
"",
[],
[],
mockup_scaleandmove_horizontal)
main()
Posts: 6,386
Threads: 278
Joined: Oct 2016
Reputation:
566
Operating system(s):
Gimp version: 3.00RC1
No idea...
Otherwise very many oddities... how much of this comes from ChatGPT or equivalent?
Posts: 4
Threads: 1
Joined: Mar 2024
Reputation:
0
Operating system(s):
- Windows Vista or 7, 8, 10 (64-bit)
Gimp version: 2.10
(03-28-2024, 09:14 PM)Ofnuts Wrote: No idea...
Otherwise very many oddities... how much of this comes from ChatGPT or equivalent?
I used it to get the right commands for the image transformations and the general usage for a gimp plugin, but noticed that it used some outdated ones. And also wrong sometimes so it was a lot of adjusting manually...
The rest i programmed myself.
Posts: 6,386
Threads: 278
Joined: Oct 2016
Reputation:
566
Operating system(s):
Gimp version: 3.00RC1
Then some suggestions:
Use the new form of registration (menu entry and menu location in distinct parameters) and avoid the useless image/drawable parameters
Code:
def mockup_scaleandmove_horizontal(): # No arguments until you add useful ones such as inpout/output directories
# Current code goes here
register(
"python_fu_mockup_scaleandmove_horizontal",
"Rescale, paint stroke, and save images",
"Rescale the input image into 5 different sizes, paint a stroke around the scaled and moved original image, and save them with DPI set to 300.",
"Daniel Kunz",
"Daniel Kunz",
"2024",
"Mockup ScaleAndMove Horizontal",
"",
[],
[],
mockup_scaleandmove_horizontal,
menu="<Image>/Filters/")
Avoid the "parallel arrays" "anti-pattern", use an array of tuples:
Code:
mockups = [
("WoodFrame_1.jpg", 295, 611, 1461, 850),
("BlackBorder_1.jpg", 113, 236, 801, 540),
("Gaming_1.jpg", 212, 112, 492, 290),
("Gaming_2.jpg", 303, 171, 436, 270),
("LivingRoom_1.jpg" 163, 115, 699, 435),
]
Then iterate and unpack the mockups:
Code:
for index, mockup in enumerate(mockups):
pdb.gimp_image_scale(original_image, scale_x[index], scale_y[index])
pdb.gimp_layer_translate(outline_layer, pos_x[index], pos_y[index])
becomes:
Code:
for mockup, pos_x, pos_y, scale_x, scale_y in mockups:
pdb.gimp_image_scale(original_image, scale_x, scale_y)
pdb.gimp_layer_translate(outline_layer, pos_x, pos_y)
Instead of loading two separate images, and copying a layer from the second to the first, you can use pdb.gimp_file_load_layer(image, filename) to load a file directly as a layer (that you still need to insert at the right position).
Since your code changes the context (the whole of set_stroke_params() (which in passing you can call only once outside of the loops)), you can bracket the whole script between pdb.gimp-context-push() and pdb.gimp-context-pop() calls to restore the initial context when done.
Use os.path.splitext() to extract the root name of a file, and os.path.join() to create a full path from directories and file names.
Code:
output_foldername = "{}".format(filename_original[:-4])
is definitely the weirdest line of code, because it is just a very complicated way to do
Code:
output_foldername = filename_original[:-4]
or more properly (see above):
Code:
output_foldername = os.path.splitext(filename_original)[0]
Posts: 4
Threads: 1
Joined: Mar 2024
Reputation:
0
Operating system(s):
- Windows Vista or 7, 8, 10 (64-bit)
Gimp version: 2.10
(03-29-2024, 08:20 AM)Ofnuts Wrote: Then some suggestions:
Use the new form of registration (menu entry and menu location in distinct parameters) and avoid the useless image/drawable parameters
Code:
def mockup_scaleandmove_horizontal(): # No arguments until you add useful ones such as inpout/output directories
# Current code goes here
register(
"python_fu_mockup_scaleandmove_horizontal",
"Rescale, paint stroke, and save images",
"Rescale the input image into 5 different sizes, paint a stroke around the scaled and moved original image, and save them with DPI set to 300.",
"Daniel Kunz",
"Daniel Kunz",
"2024",
"Mockup ScaleAndMove Horizontal",
"",
[],
[],
mockup_scaleandmove_horizontal,
menu="<Image>/Filters/")
Avoid the "parallel arrays" "anti-pattern", use an array of tuples:
Code:
mockups = [
("WoodFrame_1.jpg", 295, 611, 1461, 850),
("BlackBorder_1.jpg", 113, 236, 801, 540),
("Gaming_1.jpg", 212, 112, 492, 290),
("Gaming_2.jpg", 303, 171, 436, 270),
("LivingRoom_1.jpg" 163, 115, 699, 435),
]
Then iterate and unpack the mockups:
Code:
for index, mockup in enumerate(mockups):
pdb.gimp_image_scale(original_image, scale_x[index], scale_y[index])
pdb.gimp_layer_translate(outline_layer, pos_x[index], pos_y[index])
becomes:
Code:
for mockup, pos_x, pos_y, scale_x, scale_y in mockups:
pdb.gimp_image_scale(original_image, scale_x, scale_y)
pdb.gimp_layer_translate(outline_layer, pos_x, pos_y)
Instead of loading two separate images, and copying a layer from the second to the first, you can use pdb.gimp_file_load_layer(image, filename) to load a file directly as a layer (that you still need to insert at the right position).
Since your code changes the context (the whole of set_stroke_params() (which in passing you can call only once outside of the loops)), you can bracket the whole script between pdb.gimp-context-push() and pdb.gimp-context-pop() calls to restore the initial context when done.
Use os.path.splitext() to extract the root name of a file, and os.path.join() to create a full path from directories and file names.
Code:
output_foldername = "{}".format(filename_original[:-4])
is definitely the weirdest line of code, because it is just a very complicated way to do
Code:
output_foldername = filename_original[:-4]
or more properly (see above):
Code:
output_foldername = os.path.splitext(filename_original)[0]
Thank you so much. This made the code so much clearer and made me understand the gimp scripting better!
It works perfectly...
|