How to read an image in as a byte array using Perl?
I have very little Perl experience.
I need to read a binary image in and pass it to the Image::ExifTool
module.
Here is my code:
use Image::ExifTool;
my $exifTool = new Image::ExifTool;
open(IMAGE, $file) || die "Can't Open $file\n";
binmode(IMAGE);
my ($buf, $data, $n);
while (($n = read FILE, $data, 4) != 0) {
$buf .= $data;
}
#'.=' is concat
print $file .= " test";
$infob = $exifTool->ImageInfo(\$buf);
foreach ( keys %$infob ) {
print "$_ => $$infob{$_}\n";
}
close(IMAGE开发者_StackOverflow中文版);
As far as I can tell, my above code reads in the reference file and appends at the byte level the binary data to $buf
.
As per the ExifTool documentation, you can pass an in memory reference to a file as a scalar var to the ImageInfo method -- this is done above.
When executed, the Image::ExifTool module spits out the following:
Error => Unknown file type
use Image::ExifTool;
my $exifTool = new Image::ExifTool;
open( my $IMAGE, $filename ) || die "Can't Open $filename\n";
binmode($IMAGE);
$infob = $exifTool->ImageInfo($IMAGE);
foreach ( keys %$infob ) {
print "$_ => $$infob{$_}\n";
}
close($IMAGE);
open takes a file handle, not a scalar. Hence IMAGE
, not $IMAGE
This will cause you trouble later should you try to do a read. I.e., you want
$n = read IMAGE, $data, 4;
to actually get data from the file. Expanding on the previous code:
use Image::ExifTool;
my $exifTool = new Image::ExifTool;
$filename = $ARGV[0];
open( my $IMAGE, $filename ) || die "Can't Open $filename\n";
binmode($IMAGE);
$infob = $exifTool->ImageInfo($IMAGE);
foreach ( keys %$infob ) {
print "$_ => $$infob{$_}\n";
}
$n = read $IMAGE, $data, 2;
printf ("read %d bytes: [%s]\n", $n, $data);
$ret = close($IMAGE);
print "close returned $ret\n";
Gives this:
GreenMask => 0x0000ff00
BMPVersion => Windows V4
NumColors => 2
PixelsPerMeterX => 3938
RedMask => 0x00ff0000
Planes => 1
FileType => BMP
<snip>
read 2 bytes: [^@^@]
close returned 1
Note that the read did not work properly--should have returned BM for the first two bytes of a bitmap file. The reason is the open call does not take a scalar, it takes a file handle:
use Image::ExifTool;
my $exifTool = new Image::ExifTool;
$filename = $ARGV[0];
open( IMAGE, $filename ) || die "Can't Open $filename\n";
binmode(IMAGE);
$infob = $exifTool->ImageInfo($filename);
foreach ( keys %$infob ) {
print "$_ => $$infob{$_}\n";
}
$n = read IMAGE, $data, 2;
printf ("read %d bytes: [%s]\n", $n, $data);
$ret = close(IMAGE);
print "close returned $ret\n";
This gives:
Megapixels => 0.994
Directory => .
ImageWidth => 850
ImageSize => 850x1169
BitDepth => 1
<snip>
FilePermissions => rw-r--r--
Compression => None
NumColors => 2
FileName => staves.bmp
BlueMask => 0x000000ff
read 2 bytes: [BM]
close returned 1
The read worked properly and the ExifTool also worked.
(Hoping the formatting is okay. I'm new to this....)
精彩评论