LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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 05-11-2011, 04:21 AM   #1
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Rep: Reputation: 2
Help with converting PNG to JPG (every 0.5 seconds)


Hello everyone!

I'm trying to figure out how to solve the following problem:

I'm generating a PNG every 0.5 seconds (this PNG always overwrites itself)
Because a PNG file is too large, I need to convert it to JPG.

I made a script:

Code:
#!/bin/sh
while [ true ]; do
 /usr/bin/convert /home/file.png /var/www/html/website/file.jpg
 uleep 500
done
This script doesn't work well, because many times the conversion happens before the png file was completely written (as I said, this PNG is generated every 500 ms), so the jpg file will often result in a damaged picture, half a picture, etc.
Is there any way I can tell the "convert" command to do the conversion ONLY when the PNG was completely written on the HDD, and not before?
 
Old 05-11-2011, 05:07 AM   #2
jadrevenge
Member
 
Registered: Mar 2011
Location: Manchester,UK
Distribution: OpenIndiana/Ubuntu
Posts: 37

Rep: Reputation: 2
#!/bin/sh
while [ true ]; do
while ! ( /usr/bin/convert -quiet -regard-warnings /home/file.png /tmp/$$.jpg 2>/dev/null ) ; do
sleep 0.02
done
cp /tmp/$$.jpg /var/www/html/website/file.jpg
sleep 0.5
done
 
Old 05-11-2011, 05:15 AM   #3
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Bookworm (Fluxbox WM)
Posts: 1,391
Blog Entries: 54

Rep: Reputation: 360Reputation: 360Reputation: 360Reputation: 360
You could make use of the inotify-tools package, which allows you to script inotify events:
Code:
#!/bin/sh
while [ true ] ; do
   inotifywait -e close_write file.png
   /usr/bin/convert file.png file.jpg
   echo "converted"
done
You cannot just check whether the file has been closed (eg using 'lsof file'), because you will still have a race condition.

The above script also has a race condition, but hopefully 500ms is long enough to do the conversion before the next write to the png. An improvement would be to do the conversion to a temporary file, and test the return value from the convert command; if it gives an error, then don't copy the temporary file to the public one.

Incidentally, is the 'usleep' command you were using a 500 millisecond sleep or a 500 microsecond sleep?
 
Old 05-11-2011, 05:59 AM   #4
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Original Poster
Rep: Reputation: 2
Thanks a lot to both of you for your answers.

@neonsignal: You are right, I was using microseconds.

Here's the script I'm using now:

Code:
#!/bin/sh
while [ true ]; do
inotifywait -e close_write /home/file.png
while ! ( /usr/bin/convert -quiet -regard-warnings /home/file.png /tmp/$$.jpg 2>/dev/null ) ; do
sleep 0.02
done
cp /tmp/$$.jpg /var/www/html/website/file.jpg
sleep 0.5
done
Even though it works MUCH better now, every 20 seconds or so, one or two of the converted JPGs is still corrupted. I have no idea why...

Later edit: inotify also shows these:

Code:
Watches established.
/home/file.png IGNORED
Setting up watches.
Watches established.
/home/file.png IGNORED
Setting up watches.
Watches established.
/home/file.png IGNORED
Setting up watches.
Watches established.
/home/file.png IGNORED
Setting up watches.
Watches established.
/home/file.png IGNORED

Last edited by andy2008; 05-11-2011 at 06:07 AM.
 
Old 05-11-2011, 06:50 AM   #5
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Bookworm (Fluxbox WM)
Posts: 1,391
Blog Entries: 54

Rep: Reputation: 360Reputation: 360Reputation: 360Reputation: 360
This probably means that the generating program is not just rewriting the file, but recreating it (which means the inotify returns with an error, because it loses the node). So this following script instead waits on a notify on the directory; however, it also has to test which file was written to (on the assumption that there might be other files in the same directory).

Code:
#!/bin/sh
while [ true ] ; do
   inotifywait -e close_write /home | grep 'file.png'
   if [ $? -eq 0 ] ; then
      /usr/bin/convert file.png file.jpg
   fi
done
If the inotify is working correctly, you do not need the half second delay.
 
Old 05-11-2011, 07:21 AM   #6
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Original Poster
Rep: Reputation: 2
Well, now the output has changed:

Quote:
/home/ CLOSE_WRITE,CLOSE file.png.swp
Setting up watches.
Watches established.
/home/ CLOSE_WRITE,CLOSE file.png.swp
Setting up watches.
Watches established.
/home/ CLOSE_WRITE,CLOSE file.png.swp
Setting up watches.
Watches established.
/home/ CLOSE_WRITE,CLOSE file.png.swp
Setting up watches.
Watches established.
/home/ CLOSE_WRITE,CLOSE file.png.swp
So, it looks like there is actually a renaming going on... but it still doesn't work.
Using your latest script, brings us back to the beginning... corrupted JPGs every 1-2 seconds.
I don't understand why file.png gets ignored, even though it's constantly replaced...

Last edited by andy2008; 05-11-2011 at 07:23 AM.
 
Old 05-11-2011, 03:00 PM   #7
jadrevenge
Member
 
Registered: Mar 2011
Location: Manchester,UK
Distribution: OpenIndiana/Ubuntu
Posts: 37

Rep: Reputation: 2
you could try it with a dollar after the filename:

Code:
#!/bin/sh
while [ true ] ; do
   inotifywait -e close_write /home | grep 'file.png$'
   if [ $? -eq 0 ] ; then
      /usr/bin/convert file.png file.jpg
   fi
done
 
Old 05-11-2011, 05:42 PM   #8
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Bookworm (Fluxbox WM)
Posts: 1,391
Blog Entries: 54

Rep: Reputation: 360Reputation: 360Reputation: 360Reputation: 360
We may need to know more about the image generation sequence. As you say, the originating program may be creating the temporary (.png.swp) and then renaming it, in which case you would have to wait for a 'move-to' event rather than a 'close-write' event, eg:

Code:
#!/bin/sh
while [ true ] ; do
   inotifywait -e move_to /home | grep 'file.png$'
   if [ $? -eq 0 ] ; then
      /usr/bin/convert file.png file.jpg
   fi
done
(jadrevenge has added the '$' to prevent it matching on 'file.png.swp', which is triggering the convert too soon.)

Last edited by neonsignal; 05-11-2011 at 06:15 PM.
 
Old 05-12-2011, 12:14 AM   #9
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Original Poster
Rep: Reputation: 2
Again, thanks for all the help, guys.

Using "moved_to" for the inotifywait event seems to do the trick, it matches the file correctly:

Code:
/ramcache/ MOVED_TO file.png
Setting up watches.
Watches established.
/ramcache/ MOVED_TO file.png
Setting up watches.
Watches established.
/ramcache/ MOVED_TO file.png
Setting up watches.
Watches established.
I'm now using this script, which seems to work best, but still not 100% OK:

Code:
#!/bin/sh
while [ true ] ; do
   inotifywait -e moved_to /ramcache | grep 'file.png$'
   if [ $? -eq 0 ] ; then
      /usr/bin/convert /ramcache/file.png /ramcache/$$.jpg 2>/dev/null
      usleep 1000
      cp /ramcache/$$.jpg /var/www/html/website/file.jpg
   fi
done

With this script the conversion process works much better, but every 30 seconds or so, I still get corrupted JPGs.
I even created a ramdisk to speed up caching, but it doesn't seem to help a lot.

Last edited by andy2008; 05-12-2011 at 12:15 AM.
 
Old 05-13-2011, 02:04 AM   #10
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Original Poster
Rep: Reputation: 2
Solved it !!
The problem was : cp /ramcache/$$.jpg /var/www/html/website/file.jpg
I changed it to: mv /ramcache/$$.jpg /var/www/html/website/file.jpg

Now the corrupted JPGs have disappeared.

Now, another problem:
Is there some way to send the whole " inotifywait -e moved_to /ramcache | grep 'file.png$' " to /dev/null?
I tried various ways but it doesn't seem to work.

Later edit: Never mind, " inotifywait -e moved_to /ramcache 2>/dev/null | grep 'file.png$' >/dev/null " seems to do the trick. Thank you, neonsignal and jadrevenge for all the help !

Last edited by andy2008; 05-13-2011 at 03:18 AM.
 
Old 05-13-2011, 07:16 AM   #11
arizonagroovejet
Senior Member
 
Registered: Jun 2005
Location: England
Distribution: openSUSE, Fedora, CentOS
Posts: 1,094

Rep: Reputation: 198Reputation: 198
Did you look at whether it's possible to make whatever it is that's producing the PNG file send it's output to stdout instead of a file? Because if you can do that you could pipe it's output to convert to produce a JPEG and save yourself all this hassle with ionotify.
 
Old 05-14-2011, 12:49 AM   #12
andy2008
Member
 
Registered: Nov 2010
Posts: 40

Original Poster
Rep: Reputation: 2
No, unfortunately it can only save the PNGs in a specified folder.
 
  


Reply



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
how do i convert to from gd2 (png, jpg) whysyn Linux - Software 3 09-18-2009 02:40 PM
Converting .png to .jpg GtkUser Linux - Software 9 04-17-2007 02:04 PM
png/jpg text files? phantom_cyph General 1 04-05-2007 12:43 PM
how to show phtos(.jpg,.png etc) using java pranith Programming 1 01-08-2005 12:04 PM
pnp to png or jpg illtbagu Linux - Newbie 1 01-26-2003 03:08 PM

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

All times are GMT -5. The time now is 07:03 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