将图像二进制数据呈现到img或canvas标记中
render an image binary data into a img or canvas tag
我有一个路由,我用它来请求图像,像这样:
/api/image
它返回文件数据的主体,类似于
����JFIF��C��C��� ��
�����+�}Yϭ�F39M>���������>���;��ˋ��uXʽ�w�ڤx'-[2g��k�S���H���m
[�V?[_W����#��v��}6�[��F�F�%����n�...
我要做的是像这样:
<canvas>
然后我这样做了:
代码:var canvas = $('canvas');
var blob = new Blob([file], {type: 'image/png'});
var url = URL.createObjectURL(blob);
var img = new Image;
var ctx = canvas.getContext('2d');
$(img).on('load',function(event) {
ctx.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
}).each(function(){
if(this.complete) { $(this).load() }
});
img.src = url;
我还直接将文件附加到图像源属性中,如:
img。SRC = 'data:image/png;base64,' + file
但是不工作
我得到的是资源没有找到,它抛出404错误:
> GET blob:http://localhost:3000/2a86de11-b565-4578-8ec1-2c20cbdae739 404 (Not Found)
我有点困惑,我做错了什么?
编辑:我刚刚做了这个:
var blob = new Blob([file], {type: 'image/png'});
var reader = new FileReader();
reader.onload = function (e) {
suggestion.img.attr('src', e.target.result);
};
reader.readAsDataURL(blob);
但是它也不显示图像
好吧,您所显示的顶部数据是二进制的,因此,只是加上dataURL的东西是行不通的。您需要对二进制数据做一些不同的处理,或者返回实际的base64编码数据。
下面是一个复合示例。它表明:
- 读取磁盘上的文件
- 显示
- 上传它
- 使用GD创建修改后的副本,除非它是svg
- 将其作为二进制数据发送回浏览器 抓住它
- 将其转换为blob,然后是dataURL 在最终使用它设置图像的src属性之前。
- base64编码,添加dataURL内容并输出。
- 检索异地或跨协议图像并在画布上绘制而不污染它。
base64.php
<?php
// usefull for images without CORS header
if (isset($_GET['filename']) == true)
{
$filename = urldecode( $_GET['filename'] );
$data = file_get_contents($filename);
$finfo = new finfo(FILEINFO_MIME);
$mimeType = $finfo->buffer($data);
Header("Content-Type: $mimeType"); // use the currently detected mime-type
echo $data;
die;
}
if (isset($_FILES['upload']) == true)
{
$alterResult = true;
// GD wont load svgs :(
if (strcmp(trim($_FILES['upload']['type']),"image/svg+xml") == 0)
$alterResult = false;
// expecting a form element with the type of 'file' and the name of 'upload' - accepting 1 file max
$data = file_get_contents( $_FILES['upload']['tmp_name'] );
// draw copy of image, invert the colours, guassian blur 5 times, draw inverted,bluury image beside unaltered copy
if ($alterResult == true)
{
$mImage = imagecreatefromstring ($data);
$output = imagecreatetruecolor(imagesx($mImage) * 2, imagesy($mImage));
imagesavealpha ( $mImage , true);
imagesavealpha ( $output , true);
imagecopy($output, $mImage, 0, 0, 0, 0, imagesx($mImage) - 1, imagesy($mImage) - 1);
imagefilter($mImage,IMG_FILTER_NEGATE);
imagefilter($mImage,IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($mImage,IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($mImage,IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($mImage,IMG_FILTER_GAUSSIAN_BLUR);
imagefilter($mImage,IMG_FILTER_GAUSSIAN_BLUR);
imagecopy($output, $mImage, imagesx($mImage), 0, 0, 0, imagesx($mImage) - 1, imagesy($mImage) - 1);
Header("Content-Type: image/png");
imagepng($output);
imagedestroy($mImage);
imagedestroy($output);
die;
}
// it's an svg, so just return byte-for-byte what we received
else
{
$finfo = new finfo(FILEINFO_MIME);
$mimeType = $finfo->buffer($data);
$mimeType = preg_replace("/text'/plain/", "image/svg+xml", $mimeType); // svgs are wrongly reported as text files
Header("Content-Type: $mimeType"); // use the currently detected mime-type
echo $data;
die;
}
}
?><!doctype html>
<html>
<head>
<script>
function byId(id){return document.getElementById(id)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load',onDocLoaded);
function onDocLoaded(evt)
{
byId('fileInput').addEventListener('change', onFileChosen);
// cross origin test
var can = newEl('canvas');
var ctx = can.getContext('2d');
var srcImg = byId('crossOrigin');
can.width = srcImg.naturalWidth;
can.height = srcImg.naturalHeight;
ctx.drawImage(srcImg, 0,0);
document.body.appendChild(can);
console.log( can.toDataURL() );
}
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onload = function(evt){onLoad(this);}
ajax.onerror = function(evt){onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
function ajaxGetBinary(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.responseType = 'arraybuffer';
ajax.onload = function(evt){onLoad(this);}
ajax.onerror = function(evt){onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
function ajaxPostForm(url, formElem, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.open("POST", url, true);
ajax.responseType = 'arraybuffer';
ajax.onload = function(evt){onLoad(this);}
ajax.onerror = function(evt){onError(this);}
ajax.send( new FormData(formElem) );
}
function onFileChosen(evt)
{
// just clear the images if no file selected
if (this.files.length < 1)
{
byId('beforeImg').src = '';
byId('afterImg').src = '';
return;
}
var file = this.files[0]; // used to set the mime-type of the file when we get it back
/*
==========Before upload/download==========
*/
let fileReader = new FileReader();
fileReader.onload = function(evt){byId('beforeImg').src=this.result;}
fileReader.readAsDataURL(file);
/*
==========After upload/download==========
send the file to the backend (also this source-file), then the back-end will read the temporary file and output it.
we catch this binary output and make an image element with it
*/
ajaxPostForm('<?php echo $_SERVER['PHP_SELF']; ?>', byId('mForm'), onPostOkay, function(){});
function onPostOkay(ajax)
{
let arrayBuffer = ajax.response;
if (arrayBuffer)
{
let byteArray = new Uint8Array(arrayBuffer);
let blob = new Blob([byteArray], {type: file.type });
byId('afterImg').src = URL.createObjectURL(blob);
}
}
}
</script>
<style>
.panel
{
display: inline-block;
padding: 8px;
border-radius: 8px;
border: solid 1px black;
text-align: center;
}
</style>
</head>
<body>
<!-- RESULT of below: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA......." -->
<img id='crossOrigin' src='base64.php?filename=https%3A%2F%2Fmy.totalwellbeingdiet.com%2Fimg%2Fcsiro%2Flogos%2Fcsiro.png'/>
<!-- RESULT of below: "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported." -->
<!-- <img id='crossOrigin' src='https://my.totalwellbeingdiet.com/img/csiro/logos/csiro.png'/> -->
<form id='mForm' method='post' enctype="multipart/form-data">
<input id='fileInput' type='file' name='upload'/>
</form>
<div class='panel'>
<img id='beforeImg'/><br>
<strong>Before upload</strong>
</div>
<div class='panel'>
<img id='afterImg'/><br>
<strong>After upload/mod/download</strong>
</div>
</body>
</html>
你不应该自己构造blob, responseType应该是blob
相关文章:
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 如何更改<svg>标记为<img>用js标记
- 有没有一种方法可以防止img get请求使用css或js发生
- Javascript:使用绝对路径设置img src
- Setting default onclick behavior for <img> tag in gene
- IE9的HTML5 Canvas getImageData()函数存在问题
- 如何在页面加载中使用Jquery/Javascript确定img源
- Canvas+svg路径动画,在路径中的特定点暂停一段时间,然后继续
- 图像可以从源<img src=""/>.TEXT可以在没有javascript的情况下从外部
- 使用AngularJs时,如何在img标记具有src-attr时设置数据src
- 插入“;img src"在javascript中
- 查找带有边框的HTML5 Canvas(点击)事件的坐标
- 使用canvas或img进行频繁更新的最佳方式
- canvas.toDataURL to img src
- Canvas to img with src blob
- Javascript canvas.toDataUrl()将图片发送到<img>元素
- 将Canvas插入img标记
- 将图像二进制数据呈现到img或canvas标记中
- 使用canvas元素作为图像的缓冲区更有利,还是使用img元素作为缓冲区更有益
- Javascript Pdfjs Canvas to Img