base64图片上传图片
可以让别人看不到你的路径,还要base64可以存入数据库,
Ⅱ 详述图片base64加密的原理,告诉你什么是"/9j/"
在日常的生活中,我们肯定都经历过类似这样的场景:报名考试上传图片,网站要求的是上传的照片不能大于多少,而且要求是“.jpg”的格式。
于是你高高兴兴地把自己最漂亮的照片上传上去了,但是网站却提示你照片格式不正确,让你重新上传。这个时候内心不知道有多少疑惑涌上心头(其实是奔腾)我的照片明明就是“.jpg”结尾的,而且大小也符合规范,为啥就不行呢?
我们通常的会认为(Windows电脑情况下,Mac不知道,毕竟我没有图片)“.jpg”图片结尾的就一定是符合规范的“JPG”文件类型。其实一开始我也是这样认为的,直到前几天,我在对接项目的时候踩了一个大坑,很大的坑!
我对接的项目要求的是图片是“JPG”类型的文件,并且经过base64进行编码之后要以"/9j"开头的文件。于是我就把我电脑上保存的看似符合规范的图片上传上去了,结果就是一堆报错信息。于是我再次尝试,换一些其他的图片进行测试,发现有的就好使,有的就不好使。说实话,我的内心崩溃了!那种感觉你懂得图片
回到家之后我思来想去就是不知道为什么要求什么"/9j"开头的?我打开了网络,输入了关键词“/9j”之后,呵呵!我笑了,都是些什么?完全跟我的问题不着边!
什么玩意?这到底是什么玩意?竟然连强大的网络都没有给出结果!就这样,我搜索到了凌晨12点......
扛不住了,我就去睡觉了。但是躺在床上我辗转难眠,打开手机继续各种搜索着......突然!我看了一个关于电脑图片文件头信息解析的文章!一道灵光从我脑门上闪过。于是我起床,默默打开了电脑,打开了网络......
原来电脑在存储的时候是存储了图片的基本信息的,比如图片是什么类型的,图片的宽高等基本信息,这些个基本信息叫做图片头信息。好吧!原谅我的无知,曾经的我天真的以为是按照文件后缀名区分的呢。
我们应知道,图片在计算机中存储是一个一个的像素点,最底层也是二进制文件,所以需要文件头来保存文件信息。经查找资料,我找到如下对图片不同格式的文件头标识信息(16进制标识):
于是我在电脑上保存了一个为“.jpg”后缀结尾的图片,然后使用UE这个强大的工具打开,果然不出我所料,看看这个文件的内容信息。
不出意外的话,你肯定看不懂这些东西,因为这些是16进制文件。但是重要的我已经给你标注出来了,那就是“FF D8”。
在这里我给大家稍微简单科普下base64的编码规则:假如我们有个“hello”这样的关键字进行base64编码,需要先把“hello”转换成二进制,也就是"110100011001011101100110 11001101111"。我这里给了一个ASCII表,这里对应的是10进制的,需要把十进制转化成2进制的。
关于base64 有个规定就是,一个字符转换之后如果位数不为8位,需要在高位补0,然后再6位截取,最后不够6位的,低位补0。然后把分割后的2进制转换成10进制并对照base64编码表进行解析。那么上述的“hello”的解析过程就如下:
所以“hello”base64编码之后的最终结果就是“aGVsbG8=”。也许你会疑惑,为什么多了个“=” 这个其实是base64的规定,编码完毕之后自动添加一个或两个“=”。
那么再回到“FF D8”,jpg文件的标识头,他经过base64转码之后是什么呢?
谢天谢地,可算搞明白为什么是“/9j”开头的了。其实还有另外一种方式快速查看是不是jpg格式文件。我们可以使用记事本的方式打开一个jpg文件。
打开之后,你肯定还是看不懂这些东西,但是重要的我已经给你标注出来了,那就是“JFIF”,这个是一个很重要的标识,所谓的“JFIF”就是"JPEG File Interchonge Format"即JPEG文件交换格式。
为了还原我之前明明是“.jpg”后缀的文件,但是识别失败的问题。我们把一个格式为“.png”图片,通过改后缀名的方式,改成“.jpg”。然后也用记事本打开查看文件的内容。
可以看到,并不是“JFIF”,因此这并不是一个jpg文件,所以上传无法识别。
带着问题去睡觉,果然是睡不着的!通过这次的经历,我知道了base64的编码原理,明白了文件在电脑中存储并不是靠简简单单的后缀名来区分的,而是有文件头信息的。文件到底是一个什么文件,还是要靠文件头信息来决定的。所以,你以后的程序判断文件类型千万不要仅仅判断后缀名就完事了哦!
Ⅲ html实现图片上传
html:
<section class="upload-section">
<article class="upload-piclist">
<div class="upload-file">
<input type="file" id="file" accept="image/*" multiple onchange="imgChange()"/>
</div>
</article>
</section>
css:
/* body {
margin: 0;
padding: 0;
max-width: 414px;
margin: 0 auto;
} */
.upload-fh {
background-image: url('data:image/png;base64,/NlyAAAD1klEQVRoQ+++d972/++T//++XRa2drCkDwG8E4B+A9BH8maZ2FrBkj4D8GYA+hHAKyT/thSRYiGnZtgJogeSgFNglYkgX/+/YOlgSf0AohTOkoBekj/B19KwBdcOz/++5mGm4WttHa3D892xJAspTwXX3Pae//+/+mIZ6GzAjt7iJ49RraWhf+gWnRXY0RaY2Frd/+/yB7sE9nCeW+p8Hjbm2nDAKwcahbAdGPfTGt3nM53/V00ckNMKWY8LAAAAABJRU5ErkJggg==');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 30px;
width: 30px;
}
.upload-hedaer {
height: 55px;
display: grid;
grid-template-columns: repeat(3, 1fr);
padding: 0 10px;
box-sizing: border-box;
align-items: center;
text-align: center;
background: #287cff;
color: #fff;
border-bottom: 1px solid #efefef;
font-size: 19px;
}
.upload-hedaer div:last-child {
text-align: right;
}
.upload-textarea {
width: 100%;
height: 60px;
font-size: 28px;
border: 1px solid #efefee;
max-height: 300px;
}
.upload-article-text {
width: 100%;
padding: 10px;
box-sizing: border-box;
}
.upload-file {
position: relative;
background: url('../images/z_add.png') no-repeat 50%/100% 100%;
/* width: 100px; */
height: 120px;
order: 9;
}
.upload-piclist {
padding: 0 10px;
box-sizing: border-box;
display: grid;
grid-template-columns: repeat(3, 120px);
justify-content: space-between;
grid-gap: 14px;
}
#file {
width: 100%;
height: 100%;
opacity: 0;
}
.upload-Picitem {
width: 100%;
height: 120px;
}
.upload-Picitem>img {
width: 100%;
height: 100%;
object-fit: cover;
}
.submit {
padding: 15px 0;
background-color: #287cff;
color: #fff;
text-align: center;
margin: 10px;
font-size: 20px;
border-radius: 10px;
}
.upload-sm {
padding: 10px;
box-sizing: border-box;
color: gray;
}
.upload-sm ol>li {
margin-bottom: 10px;
}
js:let picmax = 9; //限制上传数量
function imgChange() {
let file = document.getElementById('file').files;
let imglist = document.querySelectorAll('.upload-Picitem');
let piclist = document.getElementsByClassName('upload-piclist')[0];
let filelist = file.length + imglist.length > picmax ? 9 - imglist.length : file.length + imglist.length;
if (file.length + imglist.length >= 9) {
let uploadfile = document.getElementsByClassName('upload-file')[0]
uploadfile.style.display = "none"
}
for (let i = 0; i < filelist; i++) {
readerfile(file[i]).then(e => {
let html = document.createElement('div');
html.className = 'upload-Picitem'
html.innerHTML = '<img src=' + e + ' alt="pic">'
piclist.appendChild(html);
})
}
}
function readerfile(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.addEventListener("load", function() {
resolve(reader.result);
}, false)
if (file) {
reader.readAsDataURL(file)
}
})
}
//提交
function submit() {
let imglist = []
let text = document.getElementsByClassName('upload-textarea')[0].value
let piclist = document.querySelectorAll('.upload-Picitem');
for (let i = 0; i < piclist.length; i++) {
imglist.push(piclist[i].lastChild.src)
}
console.log("发布内容:", text)
console.log("图片列表:", imglist)
}
//textarea高度自适应
var autoTextarea = function(elem, extra, maxHeight) {
extra = extra || 0;
var isFirefox = !!document.getBoxObjectFor || 'mozInnerScreenX' in window,
isOpera = !!window.opera && !!window.opera.toString().indexOf('Opera'),
addEvent = function(type, callback) {
elem.addEventListener ?
elem.addEventListener(type, callback, false) :
elem.attachEvent('on' + type, callback);
},
getStyle = elem.currentStyle ? function(name) {
var val = elem.currentStyle[name];
if (name === 'height' && val.search(/px/i) !== 1) {
var rect = elem.getBoundingClientRect();
return rect.bottom - rect.top -
parseFloat(getStyle('paddingTop')) -
parseFloat(getStyle('paddingBottom')) + 'px';
};
return val;
} : function(name) {
return getComputedStyle(elem, null)[name];
},
minHeight = parseFloat(getStyle('height'));
elem.style.resize = 'none';
var change = function() {
var scrollTop, height,
padding = 0,
style = elem.style;
if (elem._length === elem.value.length) return;
elem._length = elem.value.length;
if (!isFirefox && !isOpera) {
padding = parseInt(getStyle('paddingTop')) + parseInt(getStyle('paddingBottom'));
};
scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
elem.style.height = minHeight + 'px';
if (elem.scrollHeight > minHeight) {
if (maxHeight && elem.scrollHeight > maxHeight) {
height = maxHeight - padding;
style.overflowY = 'auto';
} else {
height = elem.scrollHeight - padding;
style.overflowY = 'hidden';
};
style.height = height + extra + 'px';
scrollTop += parseInt(style.height) - elem.currHeight;
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
elem.currHeight = parseInt(style.height);
};
};
// addEvent('propertychange', change);
// addEvent('input', change);
// addEvent('focus', change);
change();
};
pic:z_add.png
Ⅳ 如何把src为base64格式的img上传到服务器
我也正在做,一起研究吧
$.post("/unifiedtool/uploadProctImg", { "img": “data:image/png;base64,...
”},function(ret){
if(ret.img!=""){
img.src = ret;
}else{
alert("upload fail");
}
});
服务器那边
String imgString =request.getParameter("img");
UserBean user = (UserBean)request.getSession().getAttribute("user") ;
String language_id = request.getParameter("language_id");
//对字节数组字符串进行Base64解码并生成图片
if (imgString == null) //图像数据为空
return "img error";
imgString = imgString.substring(imgString.indexOf(",")+1, imgString.length());
String imgFilePath = "";
BASE64Decoder decoder = new BASE64Decoder();
try
{
//Base64解码
byte[] b = decoder.decodeBuffer(imgString);
for(int i=0;i<b.length;++i)
{
if(b[i]<0)
{//调整异常数据
b[i]+=256;
}
}
//生成jpeg图片
File newPath = new File(request.getSession().getServletContext().getRealPath("/")+"download/"+user.getUserid()+"/proct/"+language_id+"/0");
if(!newPath.exists()){
newPath.mkdirs();
imgFilePath = "1.jpg";
}else{
if(newPath.list().length > 0){
imgFilePath = (newPath.list().length+1)+".jpg";
}else{
imgFilePath = "1.jpg";
}
}
//String imgFilePath = "d:\\1111.jpg";//新生成的图片
OutputStream out = new FileOutputStream(newPath+"/"+imgFilePath);
out.write(b);
out.flush();
out.close();
}
catch (Exception e)
{
return "img error";
}
return "/download/"+user.getUserid()+"/proct/"+language_id+"/0/"+imgFilePath;
ok