4

I have a problem with ImageMagick. I searched a lot, but failed to find the solution. My problem has to do with output to JPEG XR format. I'm trying to do this in PHP 7.0/7.1 on Windows 10 and Linux Debian 9 server.

My code:

<?php

if (TRUE !== extension_loaded('imagick')) {
    throw new Exception('Imagick extension is not loaded.');
}

$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));

// $image->setImageFormat('jpg'); // <-- It works 
$image->setImageFormat('jxr'); // <-- Fatal error: Uncaught ImagickException: UnableToOpenModuleFile

header("Content-Type: image/" . $image->getImageFormat());
echo $image;

$image->destroy(); 

Result phpinfo() on Windows: enter image description here

Windows app:

C:\Users\Andrei>JxrDecApp.exe
JPEG XR Decoder Utility
Copyright 2013 Microsoft Corporation - All Rights Reserved
...

C:\Users\Andrei>JxrEncApp.exe
JPEG XR Encoder Utility
Copyright 2013 Microsoft Corporation - All Rights Reserved
...

JxrDecApp.exe and JxrEncApp.exe available from any directory!

Result phpinfo() on Linux: enter image description here

Linux packages:

root@Server:~# dpkg-query -l | grep jxr
ii  libjxr-tools                    1.1-6+b1                       amd64        JPEG-XR lib - command line apps
ii  libjxr0:amd64                   1.1-6+b1                       amd64        JPEG-XR lib - libraries
root@Server:~# dpkg-query -l | grep imagick
ii  php-imagick                     3.4.3~rc2-2                    amd64        Provides a wrapper to the ImageMagick library

root@Server:~# JxrDecApp
JPEG XR Decoder Utility
Copyright 2013 Microsoft Corporation - All Rights Reserved
...
root@Server:~# JxrEncApp
JPEG XR Encoder Utility
Copyright 2013 Microsoft Corporation - All Rights Reserved
...

Fatal error on Windows:

Uncaught ImagickException: UnableToOpenModuleFile `C:\WINDOWS\system32\config\systemprofile\AppData\Local\ImageMagick\IM_MOD_RL_jxr_.dll': No such file or directory @ warning/module.c/GetMagickModulePath/830 in D:\www\temp\jxr\index.php on line 11

Fatal error on Linux:

Unable to set image format

Wiki ImageMagick:

Supported Image Formats:

JXR | RW | JPEG extended range | Requires the jxrlib delegate library. Put the JxrDecApp and JxrEncApp applications in your execution path. Read more this

ChangeLog:

2013-04-29 6.8.5-3 Cristy
Add DeleteImageArtifact() for jpeg:extent artifact (thanks to Jimmy Xie @ Microsoft).
Add support for JXR / WDP image format.

Update

echo $_SERVER['PATH']; from PHP on Windows:

c:\Program Files\ImageMagick-6.9.3-7-vc14-x64\bin\;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Program Files\Microsoft MPI\Bin\;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\;C:\Program Files\Git\cmd;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files\Java\JDK18~1.0_1\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2017.2.1\plugins\maven\lib\maven3\bin;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\nodejs\;C:\Program Files\JetBrains\IntelliJ IDEA 2017.2.1\bin\;C:\Program Files (x86)\Skype\Phone\;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps

dir:

C:\Users\Andrei>dir "c:\Program Files\ImageMagick-6.9.3-7-vc14-x64\bin\*jxr*"
11.11.2017  22:53           464 896 JXRDecApp.exe
11.11.2017  22:53           469 504 JXREncApp.exe

echo $_SERVER['PATH']; from PHP on Linux:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

execute from:

root@Server:~# which JxrEncApp
/usr/bin/JxrEncApp
root@Server:~# which JxrDecApp
/usr/bin/JxrDecApp

Question:

How to add support for JXR image format?

fmw42
  • 46,825
  • 10
  • 62
  • 80
Andrei Krasutski
  • 4,913
  • 1
  • 29
  • 35

2 Answers2

1

Good news! The JXR or JPEG Extended Range format is supported by Imagick but not in the way you want it to. How you are currently try to access it is through the use of a byte array. The maintainer of Magick.NET (Imagick .NET library) states the following in a closed issue on Github:

The format is supported but you will need to do some 'magick' to make it work. Reading JXR files will only work when you copy the file JXRDecApp.exe to your bin directory and read from a file on disk that has a .jxr extension. Reading from a byte array is not supported. It would be nice if the code of the jxrlib project (http://jxrlib.codeplex.com) could be part of ImageMagick. Maybe I should create an issue for this in the ImageMagick project. You will need to compile JXRDecApp.exe yourself because there are no binaries available.

So the JXR format is supported but not in the way you want to apply it. However, the conversion can be done through command line as described on StackOverflow here or like this.

convert input.jpg jxr:output.jpg

What remains is to write a script that executes this command to do the conversion for you. Make sure you properly secure that script and it's input and output. Good luck!

Source:

Edwin
  • 1,135
  • 2
  • 16
  • 24
  • I do not accept your answer. I know how to convert from the command line. I do it so `JxrEncApp -i test.bmp -o test.jxr -q 0.5`. I need to have my PHP code worked. – Andrei Krasutski Nov 23 '17 at 11:14
  • That is fine by me but do take note that it is not supported in the way you want it to. – Edwin Nov 23 '17 at 11:17
  • The book [High Performance Image: Shrink, Load, and Deliver Images for Speed](https://books.google.by/books?id=G8VuDQAAQBAJ&pg=PA246&dq=setImageFormat(%27jxr%27)&hl=ru&sa=X&ved=0ahUKEwj-wqTdydTXAhVLGZoKHeK8AsUQ6AEIJTAA#v=onepage&q=setImageFormat('jxr')&f=false) has an example on PHP, but it does not work for me. I want to find a solution. – Andrei Krasutski Nov 23 '17 at 11:23
  • Actually that example (if Google Translate is correct: https://www.google.by/search?tbm=bks&hl=ru&q=setImageFormat%28%27jxr%27%29) is regarding the detection of headers and then processing it accordingly (described here https://blog.elijaa.org/2016/01/29/detect-webp-jpeg2000-jpegxr-image-format-support-in-php/). You want to create an image in JXR. That's the other way around, try if your setup accepts a JXR image. – Edwin Nov 23 '17 at 11:34
  • Yes, I want to paint the watermark and give the picture to the client in `Jpeg 2000` or `JPEG XR` or `WebP` depending on what the client understands. I have problems with the JXR. I want to find a solution – Andrei Krasutski Nov 23 '17 at 11:49
-1

Some PHP packages come with their own Imagick package rather than using the system package. You might then find as a result what is supported on the command line and what PHP supports differs.

In the source PHP directly gets the list of supported formats from Imagick itself.

If it's not different versions, perhaps there is some hidden abstraction where jxr is an alias for another parent format with some specific options.

jgmjgm
  • 4,240
  • 1
  • 25
  • 18