LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 03-11-2006, 11:00 PM   #1
exodist
Senior Member
 
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374

Rep: Reputation: 47
command line image manipulation (imagemagick?)


I think imagemagick is what I need for this, and I am looking at that site now, but mor einput would be nice.

Basically I have a dual monitor setup, xinerama so both seem to be one desktop. I want each screen to have a seperate background, this is simple, open the 2 backgrounds I want int he gimp create a new image the size of my desktop and place one image on each side...

Now it gets tricky.. I have a lot of backgrounds I cannot choose between. So I wrote a perl script that chooses 2 images fromt he directory at trandom every 30 seconds. I then also have it set the background when the images are chosen... what I need is a command line tool I can use in my script to combine the 2 images side by side. whats more some images are to large and need to be scaled down.. others are small and need to be centered on the screen they will eb on.

Yeah.. I know it is a pain in the ass... but hey it's a fun task.

Any help with imagemagick or other programs on any part of what needs to be done would be helpful.
 
Old 03-12-2006, 02:30 AM   #2
exodist
Senior Member
 
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374

Original Poster
Rep: Reputation: 47
solution

ok, I got it, messing around witht he imagemagick stuff, and re-learning some basics of how to do what with images...

Anyway if anyone else is interested int he script I commented it to a certain extent, most perl people should be able to make any needed changes.

Code:
#!/usr/bin/perl
use strict;

my $ScreenHSize = 1280;
my $ScreenVSize = 1024;
my $Source = "/home/exodist/Backgrounds";
my $Tempdir = "/tmp/backswitch";
my $Formats = "jpg,png,jpeg,bmp,tif,tiff";
my $BGName = "$Tempdir/End.jpg";
my $ChangeTime = "30";

my @List;

sub Main();
sub GenerateList();
sub Shuffle();
sub SizeImage($);
sub Combine($$);
sub SetBG($);
	
MAIN:
{
	system("rm -rf \"$Tempdir\"") if (-d "$Tempdir");
	mkdir($Tempdir) || die ("$!\n");
	Main();
}

sub Main()
{
	my @Images; #Where the image names are stored during modification.
	
	GenerateList(); #Generate a list of files from the source directory
	
	while (1) #infinite loop
	{
		Shuffle(); #Shuffle the files
		my $I = 0; #Start at file 0
		while ($I < @List) #Until we hit the end of the list
		{
			foreach my $J (0 .. 1) #we need 2 files
			{
				$Images[$J] = undef; #clear this index
				while ((!($Images[$J])) && ($I < @List)) #Cycle until we get a good image (SizeImage return 0 if the image it was given could not be used) also make sure we do not go beyond the list resulting in an infinite loop
				{
					$Images[$J] = SizeImage($List[$I]); #Try this image
					$I++; #Incriment to next file
				}
			}
			if (($Images[0]) && ($Images[1])) #If we got 2 images that work
			{
				SetBG(Combine($Images[0], $Images[1])); #Set the background
				unlink($Images[0]);
				unlink($Images[1]);
				sleep($ChangeTime); #Wait until next cycle
				#We do not want it to wait if it did not find 2 good images, we want it to try again.
			}
		}
	}
}

sub GenerateList()
{
	my $Ext; #Variable for use in finding files extension.
	opendir(SOURCE, "$Source") || die ("$!\n"); #Open the source directory or die.
	foreach my $I (readdir(SOURCE))
	{
		if ($I =~ m/\..{1,4}$/ig) #Find the extension
		{
			$Ext = $&;
			$Ext =~ s/\.//ig; #Remove . from ext
		}
		else
		{
			next; #Next file
		}
		next if (!($Formats =~ m/$Ext/ig)); #Make sure the ext is in the list or go to next
		push(@List, $I); #Add the file to the list
	}
	closedir(SOURCE); #Close the source dir.
}

sub Shuffle()
{
	my $Temp; #Temporary variable for random number
	my @List2; #Second list, data is shuffled into this list
	my $Size = (@List * 2); #We use double the list size to ensure there is never a lack of slots, if we use exactly the number of files than the script will take a long time possibly forever to find the only remaining slot.
	foreach my $I (@List) #For each file
	{
		do #Do it at least once
		{
			$Temp = rand($Size); #Find a random slot
		} while ($List2[$Temp]); #get a new number if the slot is already full
		$List2[$Temp] = $I; #Place the file into the slot
	}
	@List = (); #Clear the list
	foreach my $I (@List2) #For each element of the second list
	{
		next if (!($I)); #Next element if this one is empty (list should be half full, half empty.)
		push(@List, $I); #Add the file to the end of the main list.
	}
}

sub SizeImage($)
{
	my $HSize;
	my $VSize;

	my ($Image) = @_;
	print("$Image.");
	system("nice -n 19 cp \"$Source/$Image\" \"$Tempdir/$Image\""); #Copy from source to temp, we do not want to modify the original
	my $ImageInfo = `nice -n 19 /usr/bin/identify "$Tempdir/$Image"`; #Get the info for the image
	if ($ImageInfo =~ m/ \d+x\d+ /i) #Find the dimensions from the info, we use space before and after to select the correct one, rather than the offset info
	{
		$ImageInfo = $&; #Use the found dimensions
	}
	$ImageInfo =~ s/ //ig; #Strip spaces from dimensions
	($HSize, $VSize) = split(/x/i, $ImageInfo); #seperate verticle and Horizontal dims
	
	return 0 if ((!($HSize)) || (!($VSize))); #If we did nto get both dims there is a problem, next file.
	
	if (($HSize > $ScreenHSize) || ($VSize > $ScreenVSize)) #If the image is too large in any dimension, fix it
	{
		return 0 if (system("nice -n 19 /usr/bin/convert -resize ${ScreenHSize}x${ScreenVSize} \"$Tempdir/$Image\" \"$Tempdir/$Image\"")); #Attemtp to scale image down
		print(".");
		
		#We need to get the new sizes
		$ImageInfo = `nice -n 19 /usr/bin/identify "$Tempdir/$Image"`;
		if ($ImageInfo =~ m/ \d+x\d+ /i)
		{
			$ImageInfo = $&;
		}
		$ImageInfo =~ s/ //ig;
		($HSize, $VSize) = split(/x/i, $ImageInfo);
		#------------------
	}
	
	if (($HSize < $ScreenHSize) || ($VSize < $ScreenVSize)) #If the image is smaller than the screen size, add a border
	{
		$HSize = ($ScreenHSize - $HSize) / 2; #get half the difference between the image size and the screen size on the H
		$VSize = ($ScreenVSize - $VSize) / 2; #get half the difference between the image size and the screen size on the V
		return 0 if (system("nice -n 19 /usr/bin/convert -bordercolor \"#000000\" -border ${HSize}x${VSize} \"$Tempdir/$Image\" \"$Tempdir/$Image\"")); #Attempt to add the border
		print(".");
	}
	
	print("\t");
	return "$Tempdir/$Image";
}

sub Combine($$)
{
	my ($I1, $I2) = @_;
	print("Combine.");
	
	print(".");
	system("nice -n 19 /usr/bin/convert -verbose +append \"$I1\" \"$I2\" \"$BGName\""); #Combine the 2 images
	print(".\t");
	return $BGName;
}

sub SetBG($)
{
	my ($bg) = @_;
	print(".");
	system("nice -n 19 /usr/bin/Esetroot -center \"$bg\""); #Set the background
	print(".Set\n");
}

Last edited by exodist; 03-13-2006 at 02:37 PM.
 
Old 03-13-2006, 11:33 AM   #3
edavison
LQ Newbie
 
Registered: Mar 2006
Posts: 3

Rep: Reputation: 1
Great script! Thanks for posting your solution.

I would have probably chosen a bash script with netpbm as the tools to use for this one. But, since you did the work, I did not even get a start on it.
 
Old 03-13-2006, 02:35 PM   #4
exodist
Senior Member
 
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374

Original Poster
Rep: Reputation: 47
oh, I modded the script a bit, I changed all the commands within it to run |nice -n 19 command| because the image manipulation commands would sometimes bog down the system (athlon 64 3500+ w/ 1gb ram and a tmpfs drive for the temp files).

I will mod my script above.

Oh, I also changed it to remove temp files it makes after resising the images, this is because I have TONS of images, and my temp space is a 1gb ram drive, having them all linger around was not good.

Last edited by exodist; 03-13-2006 at 02:38 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Command Line Image Editing fractal_chaos Linux - Software 8 10-03-2005 06:33 PM
ImageMagick -- Command line Graphical Suite LinuxLala Linux - News 1 07-20-2005 09:40 AM
Hardware Manipulation From Command Line LouisTheDamned Linux - Newbie 2 03-27-2004 04:42 PM
View image from command line? Rotwang Linux - General 1 03-22-2004 03:51 AM
Boot to different image from command line markb Linux - General 8 04-06-2003 09:32 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 11:12 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration