Gimp Background scaling/centering

For system help, all hardware / software topics NOTE: use Coders Corner for all coders topics.

Moderators: Krom, Grendel

Post Reply
User avatar
snoopy
DBB Benefactor
DBB Benefactor
Posts: 4435
Joined: Thu Sep 02, 1999 2:01 am

Gimp Background scaling/centering

Post by snoopy »

Thought I'd share another script.

This one is for gimp- it will load an image, center & scale it, and then save it out to \"background.jpg\" in your working directory. Yes, beware that it automatically over-writes that file if you happen to have one in the directory in that name. Save the following code to a file, and dump it in your ~/.gimp-2.6/scripts/ folder (or windows equivalent). It scales down, but never up, and preserves the original file's aspect ratio, adding bars of a selected solid color - default black.

Code: Select all

;  Background-resize
;  Simplified scaling routine.  Loads & scales an image, if needed.


(define (background-scale sourceImg
				 red
				 green
				 blue
				 width
				 height
				 )
(let*
     (
	;Declare some values used along the way
	(widthOffset 0)
	(heightOffset 0)
	(scaleFactor 1)
	(finalLayer)
	(background (list red green blue))

	;Create a new Image
	(theImage (car
			(gimp-image-new
			width
			height
			RGB
			)
		  )
	)

	(theLayer (car
			(gimp-layer-new
			theImage
			width
			height
			RGB-IMAGE
			\"theLayer\"
			100
			NORMAL
			)
		  )
	)

	;Load the source image
	(sourceImageLayer  (car
				(gimp-file-load-layer
				0
				theImage
				sourceImg
				)
			   )
	)

	;Read the size of the source image
	(sourceWidth (car
				(gimp-drawable-width
				sourceImageLayer
				)
		     )
	)

	(sourceHeight  (car
				(gimp-drawable-height
				sourceImageLayer
				)
		        )
	)
	;At this point we're done initializing things
    )

	;Create a background layer, and fill it with the selected color.
	(gimp-image-add-layer theImage theLayer 0)

	(gimp-context-set-background background)

	(gimp-drawable-fill theLayer BACKGROUND-FILL)

	;Insert the source image
	(gimp-image-add-layer
	theImage
	sourceImageLayer
	0
	)

	;Figure necessary resizing & offsetting for Monitor
	;Find the desired scale factor (source will be multiplied by this)
	;The image will be scaled down to fit, but never up, the image is 		scaled to fit in both height in width.
	(if (> sourceHeight height)
		(set! scaleFactor (/ height sourceHeight)
		)	
	)

	(if (> sourceWidth width)
		(if (> scaleFactor
			(/ width sourceWidth)
		    )
			(set! scalefactor (/ width sourceWidth)
			)
		)
	)

	;scale the image, if scaling is needed
	(if (> 1 scaleFactor)
		(gimp-layer-scale-full
			sourceImageLayer
			(* sourceWidth scaleFactor)
			(* sourceHeight scaleFactor)
			TRUE
			2
		)
	)	


	;figure the needed offset to center it on the monitor
	(set! widthOffset (/
				(- width
					(* sourceWidth scaleFactor)
				)
			  2)
	)


	(set! heightOffset (/
					(- height
						(* sourceHeight scaleFactor)
					)
			    2)
	)

	;offset the image
	(gimp-layer-set-offsets
		sourceImageLayer
		widthOffset
		heightOffset
	)

	;merge the layers
	(gimp-image-flatten theImage)

	;get the ID of the layer
	(set! finalLayer (car (gimp-image-get-active-layer theImage)))

;	Not needed for batched usage
;	(gimp-display-new theImage)

	(file-jpeg-save
		1
		theImage
		finalLayer
		\"background.jpg\"
		\"background.jpg\"
		.85
		0
		1
		1
		\"GIMP-generated background file\"
		1
		1
		0
		2
	)
)
)

(script-fu-register \"background-scale\"
  \"Background-scale\"
  \"will scale and center a source image, so it looks proper on your screen\"
  \"D3snoopy\"
  \"D3snoopy\"
  \"2009\"
  \"RGB\"
  SF-FILENAME       \"Source Image\"        \"File\"
  SF-VALUE	\"Background Color- Red\"	    \"0\"
  SF-VALUE	\"Background Color- Green\"   \"0\"
  SF-VALUE	\"Background Color- Blue\"    \"0\"
  SF-VALUE      \"Screen Width\"        	    \"1680\"
  SF-VALUE	\"Screen Height\"	    	    \"1050\"
)

(script-fu-menu-register \"background-scale\"
                         \"<Toolbox>/Filters/Background\")
Also, if you've got linux, and want to have a random file picked for you & sent through the filter, you may use this: Note that you need to pass the desired search directory to the script, and that you can optionally over-ride the random part of it with a second parameter containing the desired filename. You will want to tweak the code to match your screen resolution. Also note that it writes to a \"background.jpg\" file in the search directory, so be careful about it replacing some image that's near and dear to you.

Code: Select all

#!/bin/bash

# searches through a directory for .jpg background candidates, randomly picks one, and runs a gimp script to size & position it for background use.

# The output files is ~/background.jpg


DIR=\"$1\"
FILE=\"$2\"
RANDOM=`date '+%s'`

# find the number of files we're working with
cd $DIR
NUMBER=`ls -1 | grep .*.jpg | wc -l`
echo $NUMBER
RANDNUM=$[ ($RANDOM % $NUMBER) + 1]
echo $RANDNUM

# the random number selected represents the file number that we'd like to use.
# setting the file to be used.  If a file parameter was sent, test for existence & using, otherwise using one based on the random number generated.

if test $FILE; then
	if test -f $FILE; then
		echo \"File defined, using $FILE\"
		else
		echo \"Invalid file, picking a random one\"
		FILE=$(ls -1 | sed -n \"$RANDNUM p\")
		fi
	else
	FILE=$(ls -1 | sed -n \"$RANDNUM p\")
	echo \"Using $FILE\"
fi

echo \"Sending the file to gimp\"
echo \"Executing the following line\"
echo \"This file is sent to your home folder\"

#gimp -i -b '(scale-resize-background \"'$FILE'\" 0 0 0 1680 1050 1920 1080 0)' -b '(gimp-quit 0)'

gimp -i -b '(background-scale \"'$FILE'\" 0 0 0 1680 1050)' -b '(gimp-quit 0)'

mv \"background.jpg\" ~/

# poke the xfce desktop to update the image displayed
xfdesktop --reload
User avatar
Jeff250
DBB Master
DBB Master
Posts: 6539
Joined: Sun Sep 05, 1999 2:01 am
Location: ❄️❄️❄️

Post by Jeff250 »

Scheme! :D

You have a typo here:
(set! scalefactor (/ width sourceWidth))

You'd been camel-casing scaleFactor, and the Gimp apparently uses a case-sensitive dialect. :oops: Although it's worth pointing out that the scheme convention is to separate-words-with-hyphens as opposed to separatingWordsWithCamelCase, especially since not all dialects are case-sensitive.

This is interesting. I never would have thought that gimp plugins were this intuitive to write. Some questions:

* Could you easily replace the R/G/B fields with some kind of Gimp color-choosing widget?
* Why, instead of choosing a file in your plugin and then saving to background.jpg, you just don't do this on whatever image is currently in focus and let the user save it how she wishes? I guess that way would seem more intuitive to me, although I suppose you wouldn't be able to use it as easily from the command line, at least without some additional scheme to wrap it.
* Is there a fundamental reason why you can't scale up, or did you just not need this feature?

I'll use this as a starting point if I ever am compelled to write a Gimp plugin. :)
User avatar
snoopy
DBB Benefactor
DBB Benefactor
Posts: 4435
Joined: Thu Sep 02, 1999 2:01 am

Post by snoopy »

1. I did have the color-choosing widget in there at one point. There was some sort of a data type conflict along the way... I don't remember exactly what it was. Maybe to do with passing the parameters in the script.

2. I wrote the gimp script specifically with seamless shell script invokation in mind. I think your suggestion would be an enhancement.

3. I don't like scaling images up to fit desktops, as a philosophical opinion. Some of my potential images are ~half of my desktop resolution, so scaling them up wouldn't look good. In short, personal opinion that it shouldn't be done.
Post Reply