How to get a Image from a URL?

MagickWand for PHP is an object-oriented PHP interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning MagickWand for PHP.
Post Reply
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to get a Image from a URL?

Post by magick »

The http protocol is not accepted by MagickWand for PHP for security reasons.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: How to get a Image from a URL?

Post by mkoppanen »

Hello,

in PHP the access is restricted using allow_url_fopen ini setting which can be set on or off by the administrator.

This can be checked in the following way in the extension code:

Code: Select all

if (PG(allow_url_fopen)) {
     /* Allowed to open remotely */
} else {
    /* Not allowed */
}
Or alternatively the support could be added through PHP streams using MagickReadImageFile (the php code would look something like the following):

Code: Select all

<?php
$wand = NewMagickWand();
// this fopen checks allow_url_fopen setting
$fp = fopen('http://example.com/image.png', 'r');
MagickReadImageFile($wand, $fp);
If there is interest for this kind of functionality (?) I can provide a patch for MagickWand for PHP.
Mikko Koppanen
My blog: http://valokuva.org
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to get a Image from a URL?

Post by magick »

If you have a patch to fix MagickWand for PHP or enhance it, post a URL here and we will get it into the source distribution generally within 24 hours. Thanks.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: How to get a Image from a URL?

Post by mkoppanen »

Hello,

here is a patch to add MagickReadImageFile functionality:

http://valokuva.org/patches/magickwand/ ... gefile.txt

I compiled against PHP 4.4.9 and PHP 5.2.9 and it seems to work fine. I didn't test older PHP4 versions.

The following code should now work:

Code: Select all

<?php
$fp = fopen("http://server/image.png", "r");
$wand = NewMagickWand();
MagickReadImageFile($wand, $fp);

var_dump(MagickGetNumberImages($wand));
The patch is massive because I also cleaned the ZEND_FE and ZEND_FUNCTION to use PHP_FE and PHP_FUNCTION (which I think is nothing more than an alias but more commonly used).

Thanks,
Mikko
Mikko Koppanen
My blog: http://valokuva.org
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to get a Image from a URL?

Post by magick »

Thanks for your good work. We will get the patch in within the next few days and make a new release soon.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: How to get a Image from a URL?

Post by mkoppanen »

No problem! I got a fix ready to support ftp, http and https filenames using MagickReadImage. Should I update the current patch or provide a patch when the trunk has been updated with the previous one?
Mikko Koppanen
My blog: http://valokuva.org
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to get a Image from a URL?

Post by magick »

The trunk for MagickWand for PHP has already been updated to 1.0.8. Post your patch against that. Thanks.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: How to get a Image from a URL?

Post by mkoppanen »

Missed an svn up there. Thanks!

Here is the patch:

Code: Select all

Index: magickwand.c
===================================================================
--- magickwand.c        (revision 14082)
+++ magickwand.c        (working copy)
@@ -97,6 +97,9 @@
    If one of the pseudo-formats is found, an attempt to read it into the MagickWand is made. If the "VID:" or
    "TILE:" pseudo-formats are found, the rest of the format string is supposed to be a filename, and it is checked
    for PHP accessibility.
+
+   ftp, http and https streams are handled separately.
+
 */
 static MagickBooleanType MW_read_image( MagickWand *magick_wand, const char *format_or_file )
 {
@@ -115,8 +118,51 @@
        TSRMLS_FETCH();
 
        real_filename[0] = '\0';
+
+       /* Special check for ftp, http and https */
+       if (strlen(format_or_file) >= 6) {
+               if (strncasecmp(format_or_file, "ftp://", 6) == 0 ||
+                       strncasecmp(format_or_file, "http://", 7) == 0 || 
+                       strncasecmp(format_or_file, "https://", 8) == 0) {
+                       FILE *fp;
+                       php_stream *stream = php_stream_open_wrapper((char *)format_or_file, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
+
+                       if (!stream) {
+                               /* No stream, fail here */
+                               return MagickFalse;
+                       }
+
+                       if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_INTERNAL) == FAILURE) {
+                               php_stream_close(stream);
+                               return MagickFalse;
+                       }
 
+                       if (php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_INTERNAL, (void*)&fp, 0) == FAILURE) {
+                               php_stream_close(stream);
+                               return MagickFalse;
+                       }
 
+                       if (MagickReadImageFile(magick_wand, fp)) {
+                               unsigned long orig_img_idx = (unsigned long) MagickGetNumberImages( magick_wand );
+                               php_stream_close(stream);
+
+                               if ( MagickSetImageIndex( magick_wand, (long) orig_img_idx ) == MagickTrue ) {
+                                       while ( MagickSetImageFilename( magick_wand, (char *) NULL ), MagickNextImage( magick_wand ) == MagickTrue )
+                                               ;
+                               }
+                               MagickClearException( magick_wand );
+                               MagickResetIterator( magick_wand );
+                               return MagickTrue;
+                       } else {
+                               php_stream_close(stream);
+                               MW_API_FUNC_FAIL_CHECK_WAND_ERROR_EX_1( magick_wand, MagickWand,
+                                                                                                               "cannot read the format \"%s\"",
+                                                                                                               format_or_file );
+                               return MagickFalse;
+                       }
+               }
+       }
+
 #define PRV_VERIFY_MAGICK_FORMAT_FILE( magick_filename, colon_p, is_magick_format )  \
 {  \
        magick_filename = colon_p + 1;  \

After this the following construct should work:

Code: Select all

<?php
$wand = NewMagickWand();
MagickReadImage($wand, "http://example.com/test.png");
Mikko Koppanen
My blog: http://valokuva.org
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: How to get a Image from a URL?

Post by magick »

Thanks, we'll get your patch into the Subversion trunk by sometime tomorrow.
Post Reply