发送/显示一个base64编码的图片

22

我需要将一个 base64 编码的字符串发送给客户端。因此,我正在服务器上打开并读取一个图像文件,对其进行编码,然后将该数据与 image/jpeg 的内容类型一起发送到浏览器。 php中的示例:

$image      = $imagedir . 'example.jpg';
$image_file = fopen($image, 'r');
$image_data = fread($image_file, filesize($image));

header("Content-type: image/jpeg");
echo 'data:image/jpeg;base64,' . base64_encode($image_data);

Clientside, 我正在调用:

var img     = new Image();
img.src     = "http://www.myserver.com/generate.php";
img.onerror = function(){alert('error');}
$(img).appendTo(document.body);

由于某些原因,这并没有起作用。 onerror 总是触发。例如,在监视 FireBug 的网络任务时,它告诉我我正在接收正确的标头信息和传输字节的正确值。

如果我将那些数据发送为 Content-type: text/plain,它可以正常工作,base64 字符串会在浏览器中显示(如果我直接调用脚本)。将该输出复制并粘贴到 <img> 元素的 src 中,就可以按预期显示图像。

我在这里做错了什么?

解决方案

感谢 Pekka 指出我的错误。您不需要(也不能!)将二进制图像数据编码为 base64 字符串来使用这种方法。没有进行 base64 编码,它就能正常工作。


看起来你应该直接将src属性的值设置为响应文本(即img.src =“data:image/jpeg;base64,...”...这里的右侧可以是Ajax调用的返回值)-否则浏览器将尝试从您设置它的URL请求图像,但由于它返回的是data:image...而不是图像字节,所以无法工作。 - John Rasch
我不想要ajax调用的开销。我需要尽可能快地得到它。为了获得某种“响应”,我需要一个有效的图像来检查其宽度。 - jAndy
5个回答

14

如果您将content-type设置为image/jpeg,那么您应该只提供jpeg数据,而不是base64编码。但是您正在将结果视为html。

实际上,您正在构建数据URI,这没问题,但正如您所注意到的那样,只能作为URI使用。因此,将内容类型保留为原样(text/html),并且

echo '<img src="data:image/jpeg;base64,'.base64_encode($image_data).'">';

然后你就可以开始了。


5

我相信只使用php就可以很高效地完成这个任务... 你可以使用下面的函数来渲染以base64编码的图像数据

    function binaryImages($imgSrc,$width = null,$height = null){
    $img_src = $imgSrc;
    $imgbinary = fread(fopen($img_src, "r"), filesize($img_src));
    $img_str = base64_encode($imgbinary);

    if(isset($height) && isset($width))
    {
    echo '<img src="data:image/jpg;base64,'.$img_str.'" height="'.$height.'" width="'.$width.'"/>';
    }
    else
    {
    echo '<img src="data:image/jpg;base64,'.$img_str.'"/>';
    }
}

如何使用此函数

    binaryImages("../images/end.jpg",100,100); 

运行二进制图像函数..第一个参数是图像路径,第二个是宽度,然后是高度..高度和宽度是可选的.


这是一个很好的方法,如果有人想要不同分辨率的图像。这也会隐藏图像URL吗?如果是的话,那么如果有人想要隐藏图像URL,这也是更好的选择。 - noobie-php

3
在这种情况下,首先没有理由对图像数据进行base64编码。你想要的是普通的图像数据。
直接传递JPEG图像即可。
唯一让我感到有道理的方式是,如果你通过AJAX调用获取了generate.php的输出,并将结果直接放入src属性中。应该可以工作(尽管不能在IE < 8中使用,但我相信你知道这一点)。但是如果您可以直接调用generate.php作为图像的来源,我认为没有必要这样做。

@Pekka:恐怕我不明白你的意思?如果不使用base64编码,我该如何通过服务器脚本文件将图像发送到客户端? - jAndy
@Pekka:这个想法是在<img>的src中调用服务器脚本,这很好(这是一个信标)。非常快,比ajax call快得多。但这里的问题是无法正确获取服务器响应。因此,我的想法是通过发送不同的图像来实现。成功可以是2像素宽度,错误可以是1像素等等。 - jAndy
2
@jAndy 啊,我明白了!有趣。但是你或我可能误解了某些东西:如果您将图像的“src”设置为某个服务器端脚本,则该脚本需要发出的内容不是 base64编码。只是普通的图像数据。或者我理解错了吗? - Pekka
好的! :) 这是一种有趣的使用信标的方式,我不知道设置 src 比 Ajax 更快。很棒! - Pekka
1
你为什么要对图像数据进行base64编码呢?这并没有什么帮助。我正在为客户构建一个API,他要求发送base64图像内容。为了测试一切是否正常,我需要创建一个<img>标签并使用这些数据。+1 @mvds 快速简单的回答。(编辑)虽然在阅读评论后,听起来他似乎不需要对其进行编码。但是,问题是如何显示编码数据,这就是我需要回答的问题。 - Dustin Graham
显示剩余3条评论

0
我会推荐它: base64_encode 使用MIME base64编码数据
echo '<img src="data:image/jpeg;base64,'.base64_encode($image).'">';

0
通过纯代码在Ajax中发送,尽管这段代码只有在您想要发送的不是直接的图像,而是base64编码时才有用。
    var imgBase64 = htmlImg.src.split(',')[1];//remove extra header from base64
    var binaryData = atob(imgBase64);//convert Base64 string to binary data
    
    var arrayBuffer = new ArrayBuffer(binaryData.length);//create an ArrayBuffer to store the binary data
    var uint8Array = new Uint8Array(arrayBuffer);//8-bit view (Uint8Array)
    for (var i = 0; i < binaryData.length; i++) {//copy the binary data to the Uint8Array
        uint8Array[i] = binaryData.charCodeAt(i);
    }
    // Crea una instancia de XMLHttpRequest
    var xhr = new XMLHttpRequest();
    xhr.open("POST","../database/photouser",true);
    xhr.setRequestHeader("Content-Type", "application/octet-stream");//header to send binary data
    xhr.send(arrayBuffer);//send the binary data
    xhr.onload = function () {//callback to data from php file
        if (xhr.status === 200) {
            console.log(xhr.responseText);//completed successfully
        } else {
            console.error('Error en la solicitud');//error in the request
        }
    };
    fileInput.value="";
},100);

通常情况下,当我们生成一张图片并尝试通过Ajax发送时,如果图片是以base64格式存在,我们需要将其转换为blob格式。

htmlImg.src.split(',')[1]

它的作用是去除这部分"data:image/jpeg;base64,",只保留格式以避免发送时出现错误,在php中的收集方式如下:
//Gets the binary data from the blob
$rawData = file_get_contents("php://input");
$file = fopen("../images/users/nombre_image.jpeg", "wb");//create the file
$content = fwrite($file, $rawData);//print the data inside the file
fclose($file);//close the process
if($file == true) echo "exitoso";else echo "no se pudo";

虽然我必须补充一点,直接以base64格式发送将不被浏览器允许,因为它们有字符限制,所以显然图片将直接发送或以blob形式发送以在PHP中进行处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接