Hướng dẫn php imagecreate to base64

I'm generating an image in PHP for use in a users avatar.

Show

I start by hashing the username and then doing a hexdec() conversion on various substrings of the hash to build up a set of RGB colours.

//create image
$avatarImage = imagecreate(250, 250);

// first call to imagecolorallocate sets the background colour
$background = imagecolorallocate($avatarImage, hexdec(substr($hash, 0, 2)), hexdec(substr($hash, 2, 2)), hexdec(substr($hash, 4, 2)));

//write the image to a file
$imageFile = 'image.png';
imagepng($avatarImage, $imageFile);

//load file contents and base64 encode
$imageData = base64_encode(file_get_contents($imageFile));

//build $src dataURI.
$src = 'data: ' . mime_content_type($imageFile) . ';base64,' . $imageData;

Ideally I'd not use the intermediate step and would skip writing the image out onto disk, although I'm not sure how best to implement this?

I've tried passing $avatarImage directly to base64_encode() but that expects a string so doesn't work.

Any ideas?

View Discussion

Improve Article

Save Article

  • Read
  • Discuss
  • View Discussion

    Improve Article

    Save Article

    The base64_encode() function is an inbuilt function in PHP which is used to convert any data to base64 encoding. In order to convert an image into base64 encoding firstly need to get the contents of file. This can be done with the help of file_get_contents() function of PHP. Then pass this raw data to base64_encode() function to encode.

    Required Function:

    • base64_encode() Function The base64_encode() function is an inbuilt function in PHP which is used to Encodes data with MIME base64. MIME (Multipurpose Internet Mail Extensions) base64 is used to encode the string in base64. The base64_encoded data takes 33% more space then original data.
    • file_get_contents() Function The file_get_contents() function in PHP is an inbuilt function which is used to read a file into a string. The function uses memory mapping techniques which are supported by the server and thus enhances the performances making it a preferred way of reading contents of a file.

    Input Image:

    Hướng dẫn php imagecreate to base64

    Program:

    Output:

    iVBORw0KGgoAAAANSUhEUgAAApsAAAC4CAYAAACsNSfVAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJ
    cEhZcwAADsQAAA7EAZUrDhsAAAAZdEVYdFNvZnR3YXJdhfdsglgklAEFkb2JlIEltYWdlUmVhZHlxyWqwrwtwefd
    ...
    TeUsalQKBQKhUKhsBvK2FQoFAqFQqFQ2A1lbCoUCoVCoVAo7IYyNhUKhUKhUCgUdkMZmwqFQKBQKO0H0fxpZ1bfc

    Reference:

    • http://php.net/manual/en/function.base64-encode.php
    • http://php.net/manual/en/function.file-get-contents.php

    PHP is a server-side scripting language designed specifically for web development. You can learn PHP from the ground up by following this PHP Tutorial and PHP Examples.

    Chuyển đến nội dung

    Có nhiều giải pháp để mã hoá hình ảnh, Encode Base64 là một trong số đó. Khi chuyển hình ảnh về dạng này ảnh được hiển thị trực tiếp từ Encode Base64 Image mà không qua URL ban đầu, điều này có nghĩa là sau khi bạn đã mã hoá thì bạn sẽ dùng code đã mã hoá này thay thế cho link ảnh ban đầu.

    Cách mã hoá này có ưu điểm là giúp bạn tránh được việc link ảnh bị die, hiển thị hình ảnh nhanh hơn và không sợ bị lỗi liên quan đến https. Tuy nhiên, nó cũng có nhược điểm là khi bạn dùng để hiển thị ảnh code in ra sẽ dài và nặng hơn.

    Một chút giới thiệu về cách mã hoá này thôi. Bây giờ ta tiến hành thực hiện, các bạn làm theo hướng dẫn bên dưới.

    //C1: dùng trên host
    $path = "myfolder/myimage.png"; 'duong-dan-ảnh-trên-host
    $type = pathinfo($path, PATHINFO_EXTENSION);
    
    //C2: dùng từ URL get content về rồi mã hoá
    $path = "http(s)://mydomain.com/myimage.png"; 'duong-dan-ảnh-từ-web
    $headers = get_headers($path, 1);
    $type = $headers["Content-Type"];
    
    $data = file_get_contents($path);
    $base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
    //KQ => ảnh đã được encode sang base64

    Code trên hoạt động bằng cách lấy content và header (để xem type ảnh) của ảnh rồi sao đó đưa vào phần mã hoá trả về kết quả $base64.

    DEMO:

    	";	
    

    Bài viết mã hoá ảnh đơn giản đến đây là hết rồi, cảm ơn các bạn đã đọc <3

    Xem thêm: Chia sẻ API getlink Zing Mp3 2019

    Xin lỗi vì đã trả lời muộn cho một câu hỏi đã được trả lời, nhưng tôi không nghĩ rằng base64_decode ($ x, true) là một giải pháp đủ tốt cho vấn đề này. Trên thực tế, có thể không có một giải pháp tốt nào phù hợp với bất kỳ đầu vào nhất định nào. Ví dụ: tôi có thể đặt nhiều giá trị xấu vào $ x và không nhận được giá trị trả về sai.

    var_dump(base64_decode('wtf mate',true));
    string(5) "���j�"
    
    var_dump(base64_decode('This is definitely not base64 encoded',true));
    string(24) "N���^~)��r��[jǺ��ܡם"
    

    Tôi nghĩ rằng ngoài việc kiểm tra giá trị trả lại nghiêm ngặt, bạn cũng cần thực hiện xác thực sau giải mã. Cách đáng tin cậy nhất là nếu bạn có thể giải mã và sau đó kiểm tra một tập hợp các giá trị khả thi đã biết.

    Một giải pháp chung hơn với độ chính xác dưới 100% (gần hơn với chuỗi dài hơn, không chính xác đối với chuỗi ngắn) là nếu bạn kiểm tra đầu ra của mình để xem liệu nhiều ký tự có nằm ngoài phạm vi thông thường của ký tự utf-8 (hoặc bất kỳ mã hóa nào bạn sử dụng) hay không.

    Xem ví dụ này:

    <": Iñtërnâtiônàlizætiøn') as $char) {
      echo ord($char) . "\n";
      $english[] = ord($char);
    }
      echo "Max value english = " . max($english) . "\n";
    
    $nonsense = array();
    echo "\n\nbase64:\n";
    foreach (str_split(base64_decode('Not base64 encoded',true)) as $char) {
      echo ord($char) . "\n";
      $nonsense[] = ord($char);
    }
    
      echo "Max nonsense = " . max($nonsense) . "\n";
    
    ?>
    

    Các kết quả:

    Max value english = 195
    Max nonsense = 233
    

    Vì vậy, bạn có thể làm một cái gì đó như sau:

    if ( $maxDecodedValue > 200 ) {} //decoded string is Garbage - original string not base64 encoded
    
    else {} //decoded string is useful - it was base64 encoded
    

    Bạn có thể nên sử dụng giá trị trung bình () của các giá trị được giải mã thay vì giá trị max (), tôi chỉ sử dụng hàm max () trong ví dụ này vì đáng buồn là không có hàm ý nghĩa () tích hợp sẵn trong PHP. Thước đo bạn sử dụng (trung bình, tối đa, v.v.) so với ngưỡng nào (ví dụ: 200) phụ thuộc vào hồ sơ sử dụng ước tính của bạn.

    Tóm lại, động thái chiến thắng duy nhất là không chơi. Tôi sẽ cố gắng tránh phải phân biệt base64 ngay từ đầu.

    25 hữu ích 0 bình luận chia sẻ

    (PHP 4, PHP 5, PHP 7, PHP 8)

    base64_decodeDecodes data encoded with MIME base64

    Description

    base64_decode(string $string, bool $strict = false): string|false

    Parameters

    string

    The encoded data.

    strict

    If the strict parameter is set to true then the base64_decode() function will return false if the input contains character from outside the base64 alphabet. Otherwise invalid characters will be silently discarded.

    Return Values

    Returns the decoded data or false on failure. The returned data may be binary.

    Examples

    Example #1 base64_decode() example

    $str 'VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==';
    echo 
    base64_decode($str);
    ?>

    The above example will output:

    This is an encoded string
    

    winkelnkemper at googlemail dot com

    11 years ago

    If you want to save data that is derived from a Javascript canvas.toDataURL() function, you have to convert blanks into plusses. If you do not do that, the decoded data is corrupted:

      $encodedData = str_replace(' ','+',$encodedData);
     
    $decocedData = base64_decode($encodedData);
    ?>

    walf

    6 years ago

    Base64 for URL parameters/filenames, that adhere to RFC 4648.
    Defaults to dropping the padding on encode since it's not required for decoding, and keeps the URL free of % encodings.

    function base64url_encode($data, $pad = null) {
       
    $data = str_replace(array('+', '/'), array('-', '_'), base64_encode($data));
        if (!
    $pad) {
           
    $data = rtrim($data, '=');
        }
        return
    $data;
    }
    function
    base64url_decode($data) {
        return
    base64_decode(str_replace(array('-', '_'), array('+', '/'), $data));
    }

    martinstaemmler at gmx dot net

    13 years ago

    I had some trouble trying to let base64_decode decode base64-strings longer than ~5k chars.

    The base64-decoding function is a homomorphism between modulo 4 and modulo 3-length segmented strings. That motivates a divide and conquer approach: Split the encoded string into substrings counting modulo 4 chars, then decode each substring and concatenate all of them.

    Then instead of

    = base64_decode($encoded); ?>

    for big $encoded strings, it's saver to use

    $decoded = "";
    for (
    $i=0; $i < ceil(strlen($encoded)/256); $i++)
      
    $decoded = $decoded . base64_decode(substr($encoded,$i*256,256));
    ?>

    where 256 can be replaced by a sufficiently small modulo 4 natural.

    Tom

    15 years ago

    This function supports "base64url" as described in Section 5 of RFC 4648, "Base 64 Encoding with URL and Filename Safe Alphabet"

            function base64url_decode($base64url)
        {
           
    $base64 = strtr($base64url, '-_', '+/');
           
    $plainText = base64_decode($base64);
            return (
    $plainText);
        }
       
    ?>

    Starson

    15 years ago

    To expand on Jes' post:

    The change took place between 5.0.5 and 5.1.0.  Exactly where I don't know or care.

    In short php <= 5.0.5's base64_decode( $string ) will assume that a space is meant to be a + sign where php >= 5.1.0's base64_decode( $string ) will no longer make that assumption.  I did not see this noted in the change log.

    Please note that, as of this writing, mb_convert_encoding( $string, "UTF-8", "BASE64" ) still behaves as base64_decode( $string ) did in php <= 5.0.5 regardless of the version of php you are running.

    debug

    14 years ago

    @morgangalpin att gmail dotty com

    A better implementation would be the following regular expression:

    ^[a-zA-Z0-9/+]*={0,2}$

    Which will also detect the usage of = or == at the end of the string (and only end).

    If this regex isn't following proper RFC guidelines, please comment on it.

    A function geared specifically toward this:

    function is_base64_encoded()
        {
            if (
    preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $data)) {
                return
    TRUE;
            } else {
                return
    FALSE;
            }
        };
    is_base64_encoded("iash21iawhdj98UH3"); // true
    is_base64_encoded("#iu3498r"); // false
    is_base64_encoded("asiudfh9w=8uihf"); // false
    is_base64_encoded("a398UIhnj43f/1!+sadfh3w84hduihhjw=="); // true?>

    twm at twmacinta dot com

    14 years ago

    To follow up on Starson's post, PHP was changed to no longer treat a space as if it were a plus sign in CVS revision 1.43.2.1, which corresponds to PHP 5.1.0.  You can see what happened with a diff to branch point 1.43 at:

    http://cvs.php.net/viewvc.cgi/php-src/ext/standard/base64.c

    The CVS log indicates that this change was made to fix bug #34214 (base64_decode() does not properly ignore whitespace).

    It would seem from the comment preceding the code which was removed that the treatment of the space as if it were the plus sign was actually intentional at one time:

        When Base64 gets POSTed, all pluses are interpreted as spaces.
        This line changes them back.  It's not exactly the Base64 spec,
        but it is completely compatible with it (the spec says that spaces
        are invalid).  This will also save many people considerable
        headache.

        if (ch == ' ') ch = '+';

    However, RFC 3548 states that characters not in the Base64 alphabet should either be ignored or cause the implementation to reject the encoding and RFC 2045 says they should be ignored.  So the original code was unfortunately not fully compatible with the spec or other implementations.  It may have also masked problems with code not properly escaping POST variables.

    tobias at silverxnet dot de

    18 years ago

    I was wondering how to decode attached images within mails. Basically they are mostly JPEG files, so it was obviously to write a function that decodes JPEG images.
    I guess the plainest way to do so was the following:

    function base64_to_jpeg( $inputfile, $outputfile ) {
     
    /* read data (binary) */
     
    $ifp = fopen( $inputfile, "rb" );
     
    $imageData = fread( $ifp, filesize( $inputfile ) );
     
    fclose( $ifp );
     
    /* encode & write data (binary) */
     
    $ifp = fopen( $outputfile, "wb" );
     
    fwrite( $ifp, base64_decode( $imageData ) );
     
    fclose( $ifp );
     
    /* return output filename */
     
    return( $outputfile );
    }
    ?>

    This function decodes the given inputfile (a filename!) and saves it to the given outputfile (a filename as well) and then returns the output filename for further usage (e.g. redirect, imagejpeg() and so on).
    I thought that might be helpful.

    user at sfdsfd dot com

    3 years ago

    function is_base64($str){
            if($str === base64_encode(base64_decode($str))){
                return true;
            }
            return false;
        }

    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------

        $str = 'VGhpcyBpcyBiYXNlNjQgZW5jb2RlIHN0cmluZw==';

        if(is_base64($str)){
            print base64_decode($str);
        }

    nicolem2005 at gmail dot com

    11 years ago

    base64_decode seems to fail when decoding big files/strings. I had an issue decoding a 7MB image file. Here is a solution that worked for me:

    $decodedstring=base64_decode(chunk_split($encodedstring));

    mcalwell

    13 years ago

    I had a problem testing whether an imap message body was base64 encoded on a pre 5.2.* server.  I had been using this function on a post 5.2 server.

    I found that the function imap_base64() returns FALSE on failing to decode a string, and that I could use that to check instead.

    if(imap_base64($body)) $body = imap_base64($body);
    ?>

    nsayer at kfu dot com

    20 years ago

    I used to do uudecode as a C module, but I've discovered a really fast way to do it in PHP. Here it is:

    function uudecode($encode) {
     
    $b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
    abcdefghijklmnopqrstuvwxyz0123456789+/"
    ; $encode = preg_replace("/^./m","",$encode);
     
    $encode = preg_replace("/\n/m","",$encode);
      for(
    $i=0; $i<strlen($encode); $i++) {
        if (
    $encode[$i] == '`')
         
    $encode[$i] = ' ';
       
    $encode[$i] = $b64chars[ord($encode[$i])-32];
      }

      while(

    strlen($encode) % 4)
       
    $encode .= "=";

      return

    base64_decode($encode);
    }
    ?>

    This is the PHP equivalent to perl's unpack("u",___). That is, you need to strip the 'begin' and 'end' lines from the typical uuencoded file.

    Klaus Fehrenbacher

    19 years ago

    this script can correct the bug

    $enc = chunk_split(preg_replace('!\015\012|\015|\012!','',$enc));
    $enc = base64_decode($enc);
    ?>

    dimagolov at yahoo dot com

    13 years ago

    Here is function to decode Base 62 (see http://en.wikipedia.org/wiki/Base_62) string to number. It is used by MTA in message id, e.g. by Exim
    function base62_decode($str) {
       
    $ret= 0;
        for (
    $i= 0, $l= strlen($str); $i < $l; $i++) {
           
    $val= ord($str[$i]);
            if (
    ctype_digit($str[$i]))
               
    $val-= ord('0');
            else if (
    ctype_upper($str[$i]))
               
    $val-= ord('A') - 10;
            else if (
    ctype_lower($str[$i]))
               
    $val-= ord('a') - 36;
            else
               
    $val= 0;
           
    $ret= $ret * 62 + $val;
        }
        return
    $ret;
    }
    ?>

    zmorris at zsculpt dot com

    14 years ago

    Here is a drop-in replacement for base64_decode(), based on a faster version of morgangalpin's code:

    // workaround for bug in php 4.3.11 through 4.4.7, 5.1.2 through 5.2.4 and perhaps others (http://bugs.php.net/bug.php?id=37244)
    function    base64_decode_fix( $data, $strict = false )
    {
        if(
    $strict )
            if(
    preg_match( '![^a-zA-Z0-9/+=]!', $data ) )
                return(
    false );

            return(

    base64_decode( $data ) );
    }
    ?>

    alvaro at demogracia dot com

    13 years ago

    You can do partial decoding (e.g. from buffered input streams) if you choose a chunk length that is multiple of 4:

    $encoded

    = base64_encode('The quick brown fox jumps over the lazy dog');
    for(
    $i=0, $len=strlen($encoded); $i<$len; $i+=4){
        echo
    base64_decode( substr($encoded, $i, 4) );
    }
    ?>

    4 encoded chars represent 3 original chars. The "=" character is used as padding.

    markandrewslade at gmail dot com

    6 years ago

    The docs don't make this explicitly clear, but if you omit `$strict` or set it to `false` then invalid characters in the encoded input will be silently ignored.

    echo base64_decode('VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=='); // "This is an encoded string"
    echo base64_decode('$VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=='); // "This is an encoded string"
    echo base64_decode('$VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==', true); // false?>