JS 图片压缩上传并在iOS中矫正方向
最近在项目中,用到图片上传。如果不进行压缩再上传的话,动辄34兆的图片,上传起来会相当漫长。还有一点就是,在iOS中所拍摄的图片在本地显示是没有问题的,但是上传之后,会出现图片翻转的问题。这里需要进行校正。还有一点就是需要判断是不是GIF,如果上传的是GIF动态图的话,就不要压缩额,压缩完之后,GIF就从良了(不动了的)。可能GIF在前段有别的压缩方式,但是我不知道的方法不是好方法。
我不生产代码 爷们是代码的搬运工
话不多说,直接干上代码。下面这段代码先对GIF和一般的图片做出区分,根据不同的模块加载不同的方法。
var filechooser = document.getElementById("filechooser");
var fo = $("#tuwem_0");
filechooser.onchange = function() {
if($(".z_addImg").length == 6){ return };
var file = this.files[0];
var orientation;
if(/\/(?:gif|GIF)/i.test(file.type)){
xoupxx(file);
}else{
EXIF.getData(file, function() {
orientation = EXIF.getTag(this, 'Orientation');
var reader = new FileReader();
reader.onload = function(e) {
getImgData(this.result, orientation, function(data) {
//这里可以使用校正后的图片data了
});
}
reader.readAsDataURL(file);
}
}
虽然代码是连续的但我还是想分开来写,这样显得多。我备注的很详细(怕自己也忘记了)。GIF下要加载的函数。
function xoupxx(file){
var reader = new FileReader(); //HTML5定义了FileReader作为文件API的重要成员用于读取文件
reader.onload = function() {
var result = this.result; //result 属性包含由被指定事件触发的事件处理器返回的最后一个值,除非这个值未定义。
var img = new Image();
toPreviewer(result);
return;
};
reader.readAsDataURL(file);
}
//下面这段代码主要是为了展示出来。
function toPreviewer(dataUrl) {
var op="";
var img = new Image();
op = dataUrl;
fo.append('<input class="remo" type="hidden" name="imgPic" value="'+op+'">');
img.src = op;
var ddiv = $("<div class='z_addImg'><div class='mm'></div></div>");
ddiv.append(img);
$('.z_photo').append(ddiv);
}
JPG PNG等等图片可以压缩,转换为base64位再进行上传。
function getImgData(img, dir, next) {
var image = new Image();
image.onload = function() {
var degree = 0,
drawWidth, drawHeight, width, height;
drawWidth = this.naturalWidth;
drawHeight = this.naturalHeight;
//以下改变一下图片大小
var maxSide = Math.max(drawWidth, drawHeight);
if(maxSide > 1024) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * 1024;
maxSide = 1024;
if(drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
drawWidth = minSide;
drawHeight = maxSide;
}
}
var canvas = document.createElement('canvas');
canvas.width = width = drawWidth;
canvas.height = height = drawHeight;
var context = canvas.getContext('2d');
//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
switch(dir) {
//iphone横屏拍摄,此时home键在左侧
case 3:
degree = 180;
drawWidth = -width;
drawHeight = -height;
break;
//iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
case 6:
canvas.width = height;
canvas.height = width;
degree = 90;
drawWidth = width;
drawHeight = -height;
break;
//iphone竖屏拍摄,此时home键在上方
case 8:
canvas.width = height;
canvas.height = width;
degree = 270;
drawWidth = -width;
drawHeight = height;
break;
};
//使用canvas旋转校正
context.rotate(degree * Math.PI / 180);
context.drawImage(this, 0, 0, drawWidth, drawHeight);
//返回校正图片
//next(canvas.toDataURL("image/jpeg", .8));
//console.log(canvas.toDataURL("image/jpeg", .8));
//previewer.src = canvas.toDataURL("image/jpeg", .8); //base64
var op="";
var img = new Image();
op = canvas.toDataURL("image/jpeg", .8);
fo.append('<input class="remo" type="hidden" name="imgPic" value="'+op+'"><input type="hidden" name="isPng" value="1">');
img.src = canvas.toDataURL("image/jpeg", .8);
var ddiv = $("<div class='z_addImg'><div class='mm'></div></div>");
ddiv.append(img);
$('.z_photo').append(ddiv);
}
image.src = img;
};
后端代码很简单,这里我一并干上来!把base64转成文件
def decode_file(data):
"""
"""
imgdata=base64.b64decode(re.sub(r'data:image/.*?;base64,', '', data))
file = '.' + "".join(re.findall(r'data:image/(.*?);', data))
md = hashlib.md5()
md.update(str(random.randint(1111, 999999999)+int(time.time())))
file_name = md.hexdigest() + file
file=open(AllConf.FILE_PATH + file_name,'wb')
file.write(imgdata)
file.close()
return gif_to_png(AllConf.FILE_PATH + file_name)
def gif_to_png(file):
if 'gif' in file or 'GIF' in file:
new_file = "".join(file.split('.')[:1])
print new_file, file
x = Image.open(file)
x.convert('RGB').save(new_file + '.jpg')
gif = re.sub(AllConf.FILE_PATH, AllConf.FILE_URL, file)
png = re.sub(AllConf.FILE_PATH, AllConf.FILE_URL, new_file + '.jpg')
return gif + '&&' + png
return re.sub(AllConf.FILE_PATH, AllConf.FILE_URL, file)