dpi of png image is not changing.

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

dpi of png image is not changing.

Post by deepakd »

Hi,

I have used density(dpi) api to change the dpi of png image. dpi is not getting changed for PNG image but it works fine for JPEG image.
Please let us know whether anything I need to before or after calling density(dpi).

Reference : viewtopic.php?f=23&t=28480

Thanks,
Deepak
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: dpi of png image is not changing.

Post by dlemstra »

Can you reproduce this issue with the latest version of ImageMagick?
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: dpi of png image is not changing.

Post by glennrp »

PNG stores "resolution" in pixels/meter. But I've seen density go into a PNG text chunk with "Density" keyword, and embedded in the EXIF data. The "density()" api may be putting the density info in the wrong place (BTW I can't find a "density()" API anywhere in the ImageMagick source. Are you using a wrapper of some kind?)
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

glennrp wrote:PNG stores "resolution" in pixels/meter. But I've seen density go into a PNG text chunk with "Density" keyword, and embedded in the EXIF data. The "density()" api may be putting the density info in the wrong place (BTW I can't find a "density()" API anywhere in the ImageMagick source. Are you using a wrapper of some kind?)
Hi,

Once density is set, data is going to text chunk only. Api density is der in image.h header file.
After setting dpi we are doing following thing if it is png image.

Code: Select all

     if ((m_type == PNG)) {
            // In case anything goes wrong, we just deliver the "bad" image.
            const unsigned char *sptr = reinterpret_cast<const unsigned char *>(outputblob.data());
            const unsigned char *send = sptr + outputblob.length();

            // This is our output buffer already allocated.
            unsigned char *dptr = reinterpret_cast<unsigned char *>(output_buffer);

            // Copy PNG header (0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A)
            std::memcpy(dptr, sptr, 8 );

            try {
                enum {
                    CNK_UNSORTED,
                    CNK_TEXT,
                    CNK_IMAGE,
                    CNK_IEND,

                    CNK_LAST // END marker, don't remove
                };

                typedef std::list<cpinfo> cplist_t;
                typedef cplist_t::const_iterator cplist_c;

                cplist_t chunks[4]; // 0 = Unsorted, 1 = Text, 2 = Image, 3 = IEND

                // Skip over the PNG header in both buffers
                const unsigned char *scur = sptr + 8; // 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
                unsigned char *dcur = dptr + 8;

                // Scan chunks
                // Chunk format:
                // Offset Length Meaning
                // 0      4      Chunk length (big endian. This is length of "X" only!!)
                // 4      4      Chunk type (string)
                // 8      X      Chunk data
                // 8+X    4      CRC32 checksum

                // The PNG IHDR chunks must be the first chunk in the file, so copy him.
                bool header_processed = false;

                // This will also properly copy the IEND chunk
                while (send - scur) {
                    // This may of course scan beyond buffer's end.
                    // It's OK here - the blob IM delivered *is* valid PNG,
                    // no user-generated data or whatever.

                    // Fetch length, fill copy struct
                    const boost::uint32_t *lptr = reinterpret_cast<const boost::uint32_t *>(scur);
                    cpinfo cpi;
                    cpi.data = scur;
                    cpi.length = ntohl(*lptr);

                    // Fetch chunk type
                    scur += 4;

                    char ctype[5];
                    std::memcpy(ctype, scur, 4);
                    ctype[4] = '\0';

                    // The first chunk is IHDR, this _must_ be the first chunk so
                    // copy him to the output buffer immediately.
                    if (!header_processed) {
                        std::memcpy(dcur, cpi.data, cpi.length + 12);
                        dcur += (cpi.length + 12); // 4 length, 4 type, 4 crc32

                        header_processed = true;
                    } else {
                        // Non-IHDR chunk: Check chunk type
                        if ((std::strncmp(ctype, "tEXt", 4) == 0) || (std::strncmp(ctype, "zTXt", 4) == 0)
                                || (std::strncmp(ctype, "iTXt", 4) == 0)) {
                            // This is a text chunk 
                            chunks[CNK_TEXT].push_back(cpi);
                        } else if (std::strncmp(ctype, "IDAT", 4) == 0) {
                            // This is an image
                            chunks[CNK_IMAGE].push_back(cpi);
                        } else if (std::strncmp(ctype, "IEND", 4) == 0) {
                            // This is an IEND chunk
                            chunks[CNK_IEND].push_back(cpi);
                        } else {
                            // This is some other chunk
                            chunks[CNK_UNSORTED].push_back(cpi);
                        }
                    }

                    // Advance to next chunk. Add text length (4), payload length (X) and crc32 length (4)
                    scur += (cpi.length + 8 );
                }
Thanks,
Deepak
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

Hi,

Any one can look into this??

Thanks,
Deepak
User avatar
dlemstra
Posts: 1570
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: dpi of png image is not changing.

Post by dlemstra »

We get the expected result when we execute the following code with the latest version of ImageMagick:

Code: Select all

Magick::Image image("logo:");
image.density(Magick::Geometry("200"));
image.write("c:\\logo.png");

C:\>identify -verbose logo.png
Image: logo.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 640x480+0+0
  Resolution: 200x200
  Print size: 3.2x2.4
And we really cannot help you debug your own code.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

Hi,

We are using imagemagick-win64-vc110-6.7.6.rtt_patch.3 library, could u please let me know is there any hotfix availble?


Thanks,
Deepak
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: dpi of png image is not changing.

Post by fmw42 »

User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: dpi of png image is not changing.

Post by glennrp »

deepakd wrote: Once density is set, data is going to text chunk only. Api density is der in image.h header file.
After setting dpi we are doing following thing if it is png image.
Deepak
I couldn't see in your code anything having to do with density. I assume you created a new text chunk with the density info, with the proper chunk length and recalculated CRC, and then used your code to assemble a PNG file from the chunks, including your new or revised text chunk. Correct?
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

Deepak[/quote]
I couldn't see in your code anything having to do with density. I assume you created a new text chunk with the density info, with the proper chunk length and recalculated CRC, and then used your code to assemble a PNG file from the chunks, including your new or revised text chunk. Correct?[/quote]


Hi,

I have called density before executing the above code.

Thanks,
deepak
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: dpi of png image is not changing.

Post by glennrp »

deepakd wrote: I have called density before executing the above code.
I'm sorry, but I don't know what that means. As far as I know, we don 't supply a "density()" API, so the problem does not appear to be in ImageMagick.
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

Hi,
In order to use new version of ImageMagick library I have done following thing.

1. Downloaded http://www.imagemagick.org/download/win ... windows.7z
2. Extracted 7z file.
3. Built configure.soln file in x64 platform release mode.
4. Ran application configure.exe
5. Built VisualStaticMTD.sln file in x64 platform release mode.
6. I am using density(), Magick::Blob::data(void) etc. apis which are there in mageMagick-6.9.2-4\ImageMagick\Magick++\lib\Magick++\Image.h
7. Even though I linked CORE_RL_magick_.lib, CORE_RL_wand_.lib and CORE_RL_Magick++_.lib I am getting linker error.

Please let me know which all library I need to link to use the apis in ImageMagick-6.9.2-4\ImageMagick\Magick++\lib\Magick++\Image.h

Thanks,
Deepak
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: dpi of png image is not changing.

Post by glennrp »

deepakd wrote: 6. I am using density(), Magick::Blob::data(void) etc. apis which are there in mageMagick-6.9.2-4\ImageMagick\Magick++\lib\Magick++\Image.h
OK, so you are using the Magick++ wrapper which does indeed support a "density()" function. It sets image->x_resolution and image->y_resolutions, which get written as a pHYs chunk by the png encoder. I suspect that upgrading your ImageMagick to the current version won't change anything.

With regard to your original post, I'm still thinking there's some confusion about where the density is stored in the PNG image. What do you see when you run "identify -verbose image.png" with the image.png that you originally reported, in which density did not change from your input image? Does it contain a pHYs chunk with the density you expected, and a text chunk with the original image's density?
deepakd
Posts: 15
Joined: 2015-10-08T22:55:09-07:00
Authentication code: 1151

Re: dpi of png image is not changing.

Post by deepakd »

Hi All,

I am able to see the change in dpi using irfan view. Appreciate your effort to help me out.

Thanks,
Deepak
Post Reply