http://qs1969.pair.com?node_id=11143932

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

I have an array of 65536 values from 0-254 that makes an image after doing this:
open my $fh, '>', 'data'; binmode $fh; print $fh pack 'C*', @data; close $fh; `convert -depth 8 -size 256x256+0 gray:data data.png`;
I'd like to use Imager instead but my output is slightly scrambled:
my $img = Imager->new( type => 'raw', xsize => 256, ysize => 256, data => pack('L>*', @data), raw_interleave => 0, raw_storechannels => 1, model => 'gray' ); $img->write(file=>'data.png');
What am I doing wrong? Thank you!

Replies are listed 'Best First'.
Re: Create image from pixel values with Imager
by Discipulus (Canon) on May 17, 2022 at 07:27 UTC
    Hello,

    have you seen Re: How to create and save an image from RGB values?

    Can you give us more details about slightly scrambled results?

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Yes I did see Re: How to create and save an image from RGB values (that's where I got the Imager code :^). Was going to mention it too but didn't, to keep things brief. By "scrambled" I mean the image is somehow partially correct, as if every other line is offset or something.

        Without more information, I can only guess, but it sounds like an off-by-one error. In your OP: "65536 values from 0-254". That suggests a 255x255 square which is 65025 values; a 256x256 square is 65536 values. Do you perhaps want to start with "65536 values from 0-255"?

        Update: s/off-by-error/off-by-one error/

        — Ken

Re: Create image from pixel values with Imager
by Anonymous Monk on May 17, 2022 at 13:12 UTC

    See RAW. raw_datachannels default is 3. Either set it to 4, or better to 1 but then pack with C*.

      Thank you so much, this works perfectly:
      my $img = Imager->new( type => 'raw', xsize => 256, ysize => 256, data => pack('C*', @data), raw_interleave => 0, raw_datachannels => 1, raw_storechannels => 1 ); $img->write(file=>'data.png');
Re: Create image from pixel values with Imager
by bliako (Monsignor) on May 17, 2022 at 14:08 UTC

    I don't know your data but with my simple data:

    use constant IMAGESIZE => 5; my @data = (0x0)x(IMAGESIZE*IMAGESIZE); $data[0] = 0xAA; $data[3] = 0xBB;

    This: convert data.png data.txt shows that it still thinks data is 4 bytes long. Imager is way too complex for me and pack even more so. Perhaps modify the code supplied by vr in Re: How to create and save an image from RGB values to get only 1 channel using the combine() thingy?

    bw, bliako

Re: Create image from pixel values with Imager
by tonyc (Pilgrim) on Jun 07, 2022 at 12:05 UTC

    Unfortunately raw_datachannels doesn't follow raw_storechannels, so if you supply one, you probably need to supply the other, this also lets you switch to pack "C*" to pack the data as bytes. I don't have your data, so I can't check this does exactly what you want.

    my $img = Imager->new( type => 'raw', xsize => 256, ysize => 256, data => pack('C*', @data), raw_interleave => 0, raw_storechannels => 1, raw_datachannels => 1, model => 'gray' ); $img->write(file=>'data.png');