Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

encode/decode images

by Anonymous Monk
on Feb 25, 2009 at 19:18 UTC ( [id://746350]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks, I'm using the following snippet to encode and prepare my thumbnails (200 x 150) for insertion into PostgreSQL.
use strict; use warnings; my $buf; open(FILE, "image.jpg") or die "$!"; while (read(FILE, $buf, 60*57)) { print encode_base64($buf); }
even a small thumbnail produces a good sized string, is there any way of further shrinking the base64 encoded string?

Thanks

Replies are listed 'Best First'.
Re: encode/decode images
by almut (Canon) on Feb 25, 2009 at 19:46 UTC

    What's the idea behind the encoding?  If it's that you can't/don't want to store binary data directly, you could try ASCII85/Base85 encoding, which uses 85 "printable" characters (instead of 64), and thus is slightly more compact (25% (base85) vs. 33% (base64) larger than the binary input).  Otherwise, I don't see many possibilities to significantly compress your ascii-fied image data any further, as the original JPG input already is compressed...

    Note that there are several slightly different versions of ASCII85.  A CPAN search shows the related Perl module Math::Base85 which implements the RFC 1924 variant. Implementations of the Adobe variant might be found in the respective PDF/PS modules, though PDF::API2::Basic::PDF::ASCII85Decode seems to provide decoding only...

    Update: FWIW, Nicholas Clark seems to have written such a module. Does anyone happen to know if/under what name that ended up on CPAN?

      I was hoping to store the image as text to avoid having to bother with any binary data type stuff.

      Thanks

        That's hilarious! You want to store a jpg in your database without "bothering" with "any binary data type stuff". And you're worried about how much space it will take up. Something here just isn't adding up.

        Let's take a step back. Why are you storing images in your database? In my experience this is a bad idea 100% of the time. Instead, store your images on disk and store the path in the database. If you have multiple servers use NFS or even Amazon S3 to store the file. But not your RDBMS - that's not what it's for.

        -sam

        JPEG images ARE just binary streams. You can encode them to various ASCII/text type encodings, but all of those will increase the size of the resulting string/stream/file. You could transform the image to some pure-text image format, like XPM, but for typical JPEGs that will increase the size a lot more than a simple base64-type encoding of the original JPEG data.

        Bottom line: use "raw" binary strings when dealing with inherently binary data, unless you really need some encoding (for instance, when mailing the data or encapsulating it in an XML file).

        update: Postgres does have facilities for dealing with binary data directly. So read the docs for the right module.

Re: encode/decode images
by zentara (Archbishop) on Feb 26, 2009 at 14:16 UTC
    I agree with samtregar's advice to just store pathnames in the database....BUT assuming you know what you are doing, I think I would use base 128 encode them
    #!/usr/bin/perl use warnings; use strict; use Math::BaseCnv; #fast my $time = time; print "time -> $time\n"; my $time_128 = cnv( $time, 10, 128 ); print "time_128 -> $time_128\n"; #this will sometimes print hidden newlines my $time_back = cnv( $time_128, 128,10 ); print "timeback-> $time_back\n"; exit;

    I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
Re: encode/decode images
by scorpio17 (Canon) on Feb 26, 2009 at 15:25 UTC

    I agree with samtregar - putting images in a database is a bad idea. Store "pointers" to the files (file paths, etc.), along with other meta-data, if you want to be able to search for specific groups of images.

    But if you really want to do it anyway - just use the 'blob' datatype - that's what it's for. Just read the thumbnail image into a string (slurp the file), then write it to the database like any other string. Just don't try to view it in the mysql client! And keep all the blob data in a table of its own, else you'll kill the performance of other database queries.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://746350]
Approved by almut
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-20 04:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found