I have added a png image to a table in the database as a BLOB. Adding the image into the database is trivial. However, being able to display the BLOB back to the .png image format is bewildering me.

Examples are hard to come by... How to display the BLOB back to the image?

This simple example only displays the raw binary data:

my (@images) = query("SELECT name FROM test_file WHERE id='$id'");

foreach my $img(@images)
{
    print $img;     # Displays the blob gobble de gook
}

I have heard people using BINMODE but again, I can't get that to do anything useful:

open(IMAGE, ">/tmp/file.png");
binmode IMAGE;
print IMAGE $img;
close(IMAGE);

Any examples are much appreciated.
Regards,
ns

Dani AI

Generated

Short version: the PNG bytes in the BLOB are fine — the problem is how they are being fetched and output. Common mistakes are (a) DBI silently truncating long fields, (b) accidentally applying text/UTF-8 layers to the output, or (c) sending binary to a terminal or HTML page without the proper headers. ’s temp-file idea works, but you can avoid filesystem I/O by serving the bytes directly (or embed small images as base64).

Key example (serve the blob directly from a CGI endpoint):

# ensure DBI will return the full BLOB
$dbh->{LongReadLen} = 10_000_000;    # set to max expected blob size
$dbh->{LongTruncOk} = 0;

# fetch the blob into $blob ...
# then send an image response
print $q->header(-type => 'image/png', -Content_length => length($blob));
binmode STDOUT;                 # important: remove any text encoding layer
syswrite STDOUT, $blob;

Alternative (embed in the HTML for small images):

use MIME::Base64;
my $b64 = encode_base64($blob, '');
print qq{<img src="data:image/png;base64,$b64" alt="">};

Troubleshooting checklist

  • Confirm the BLOB actually starts with the PNG signature: first 8 bytes == 0x89 50 4E 47 0D 0A 1A 0A.
  • Set $dbh->{LongReadLen} large enough before the SELECT; otherwise DBI can truncate long fields.
  • Use binmode on the output filehandle (STDOUT or a file) so Perl does not apply UTF-8 or CRLF translations.
  • Make sure no debugging prints, whitespace, or HTML are emitted before the binary and that the Content-Type header is sent first.
  • If you do write temp files, use File::Temp and secure permissions; concurrent requests and cleanup are common pitfalls.

If you provide how the script is invoked (plain script, CGI, mod_perl, PSGI) and the DBI/driver used, a short tailored snippet can be posted.

How is this script being called? Is it a CGI script, or is it being called in some kind of GUI? As I understand it, you can't just print an image to the command line as it's not a graphical interpreter, so you must be calling this in some other context. If this is in a CGI script, you would display the image as you would display any image in a web page:

my (@images) = query("SELECT name FROM test_file WHERE id='$id'");

foreach my $img(@images)
{
    open(IMG,">$$tempfile.png") or die "Couldn't open $$tempfile.png: $!\n";
    binmode IMG;
    print IMG $img;
    echo "<img src=\"$$tempfile\.png\">";
    close IMG;    
}

Can you give us any more details about how this script is being called/used?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.