js缩放上传图片

通过朋友介绍,最近接了个项目。其中有一处的功能,需要将图片上传至微信公众号,并且是压缩过的图片。

第一时间,我想到了用js来处理。通过h5的新特性canvas来缩放图片。然后,把处理好的图片再上传至服务器。

具体代码如下,你还可以去我的github上去找 https://github.com/altwei/study-javascript

html

[code lang=”html”]
<!doctype html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<title>图片上传</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link type="text/css" rel="stylesheet" href="public/css/style.css">
</head>
<body>

<button>选择图片 – 请使用谷歌浏览器</button>

<div></div>

<script src="public/js/jquery-1.11.1.min.js"></script>
<script src="public/layer_mobile/layer.js"></script>
<script src="public/js/script.js"></script>
<script>
$(‘button’).on(‘click’, function () {
// 创建input
var input = $tag(‘input’, {type: ‘file’, name: ‘file’, multiple: true});
// 触发input
input.click();
// change事件
$(input).on(‘change’, function () {
// 读取图片文件
reader.image(this.files[0], function (image, file) {
// 缩放图片, 获取base64
// var base64 = photo.drawBase64(image, 1920, 1080);
var base64 = photo.drawBase64(image, 800, 450);
// 加入div
$(‘div’).append($tag(‘img’, {src: base64}));
// 初始上传数据
var data = new FormData();
data.append(‘file’, transcode.toBlob(base64), file.name);
// 上传文件
ajax.upload("upload.php", data, function (data) {
console.log(data);
});
});
});
});
</script>
</body>
</html>
[/code]

javascript

[code lang=”javascript”]
/**
* 异步请求
* @type {{loading: boolean, get: ajax.get, post: ajax.post, upload: ajax.upload, request: ajax.request}}
*/
var ajax = {
loading: false,
/**
* ajax get
* @param url
* @param callback
*/
get: function (url, callback) {
this.request({url: url, type: ‘get’}, callback);
},
/**
* ajax post
* @param url
* @param data
* @param callback
*/
post: function (url, data, callback) {
this.request({url: url, data: data}, callback);
},
/**
* ajax upload
* @param url
* @param formData
* @param callback
* @param progress
*/
upload: function (url, formData, callback, progress) {
var options = {
url: url,
data: formData,
processData: false,
contentType: false,
xhr: function () {
var xhr = new window.XMLHttpRequest();
if (typeof progress != ‘undefined’) {
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percent = parseInt(evt.loaded / evt.total * 100, 10);
progress(percent);
}
}, false);
}
return xhr;
}
};
this.request(options, callback);
},
/**
* ajax request
* @param options
* @param callback
* @returns {boolean}
*/
request: function (options, callback) {
//防止重复提交
if (ajax.loading) {
return false;
}
ajax.loading = true;
//添加遮罩层
lay.mask();
//合并ajax参数
var params = $.extend({
type: ‘POST’, //请求方式
timeout: 5000, //请求超时时间(毫秒)
async: true, //使用异步请求
cache: true, //使用缓存
dataType: ‘json’, //返回的数据类型
contentType: ‘application/x-www-form-urlencoded’, //发送的数据类型
processData: true, //转化成一个查询字符串
success: function (data, textStatus) {
ajax.loading = false;
console.log(data);
console.log(textStatus);
callback && callback(data);
//关闭所有layer
layer.closeAll();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
ajax.loading = false;
console.log(XMLHttpRequest);
console.log(textStatus);
console.log(errorThrown);
alert(‘系统出错:’ + textStatus);
//关闭所有layer
layer.closeAll();
}
}, options || {});
//开始ajax请求
$.ajax(params);
}
};
/**
* layer弹窗
* @type {{time: number, hint: lay.hint, mask: lay.mask, alert: lay.alert, confirm: lay.confirm}}
*/
var lay = {
time: 3,
/**
* 提示
* @param msg
*/
hint: function (msg) {
layer.open({
content: msg,
skin: ‘msg’,
time: this.time
});
},
/**
* 遮罩层 loading
*/
mask: function () {
layer.open({
type: 2,
shadeClose: false,
content: ‘加载中’
});
},
/**
* 警告提示
* @param msg
*/
alert: function (msg) {
layer.open({
content: msg,
btn: ‘确认’
});
},
/**
* 确认提示
* @param msg
* @param callback
*/
confirm: function (msg, callback) {
layer.open({
content: msg ? msg : ‘确认无误?’,
btn: [‘确认’, ‘取消’],
yes: function (index) {
layer.close(index);
callback && callback();
}
});
}

};
/**
* 读取文件/读取图片文件
* @type {{file: reader.file, image: reader.image}}
*/
var reader = {
/**
* 读取文件
* @param file
* @param callback
* @param type
*/
file: function (file, callback, type) {
var reader = new FileReader();
switch (type) {
case ‘ArrayBuffer’:
reader.readAsDataURL(file);
break;
case ‘Text’:
reader.readAsText(file);
break;
case ‘DataURL’:
default:
reader.readAsDataURL(file);
break;
}
reader.onload = function () {
callback(this.result, file)
};
},
/**
* 读取图片文件
* @param file
* @param callback
*/
image: function (file, callback) {
this.file(file, function (base64, file) {
$tag(‘img’, {src: base64}).onload = function () {
callback(this, file);
};
});
}
};
/**
* 数据转码
* @type {{toDataUrl: transcode.toDataUrl, toBlob: transcode.toBlob, toFile: transcode.toFile}}
*/
var transcode = {
/**
* Blob或File转为DataURL
* @param file
* @param callback
*/
toDataUrl: function (file, callback) {
switch (file.toString()) {
case ‘[object Blob]’:
case ‘[object File]’:
reader.file(file, callback);
break;
default:
callback && callback();
break;
}
},
/**
* DataURL转为Blob
* @param dataUrl
* @returns {Blob}
*/
toBlob: function (dataUrl) {
var arr = dataUrl.split(‘,’), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n–) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type: mime, filename: ‘fuck’});
},
/**
* DataURL转为File
* @param dataUrl
* @param filename
* @returns {File}
*/
toFile: function (dataUrl, filename) {
var arr = dataUrl.split(‘,’), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n–) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type: mime});
}
};
/**
* 图片处理
* @type {{draw: photo.draw, drawBase64: photo.drawBase64}}
*/
var photo = {
/**
* 绘制图片, 返回canvas
* @param image
* @param setWidth
* @param setHeight
* @returns {HTMLElement}
*/
draw: function (image, setWidth, setHeight) {
setWidth = setWidth === undefined ? image.width : setWidth;
setHeight = setHeight === undefined ? image.height : setHeight;
// 等比例缩放
if (image.width > setWidth) {
setHeight = image.height / image.width * setWidth;
}
if (image.height > setHeight) {
setWidth = image.width / image.height * setHeight;
}
// 绘制图片
var canvas = $tag(‘canvas’, {width: setWidth, height: setHeight});
canvas.getContext(‘2d’).drawImage(image, 0, 0, setWidth, setHeight);
return canvas;
},
/**
* 绘制图片, 返回base64
* @param image
* @param setWidth
* @param setHeight
* @param imageType
* @param imageQuality
* @returns {string | *}
*/
drawBase64: function (image, setWidth, setHeight, imageType, imageQuality) {
// 图片类型
if (imageType === undefined) {
imageType = ‘image/jpeg’;
}
// 图片质量( image/jpeg 或 image/webp )
if (imageQuality === undefined) {
imageQuality = 0.9;
}
base64 = this.draw(image, setWidth, setHeight).toDataURL(imageType, imageQuality);
return base64;
}
};

/**
* 创建html标签
* @param tagName
* @param attr
* @param append
* @returns {HTMLElement}
*/
function $tag(tagName, attr, append) {
var tag = document.createElement(tagName);
attr && $(tag).attr(attr);
append && $(tag).append(append);
return tag;
}
[/code]

php

[code lang=”php”]
<?php $tmp_name = isset($_FILES[‘file’]) ? $_FILES[‘file’][‘tmp_name’] : ”; if ($tmp_name) { $save = ‘./uploads/’ . uniqid() . basename($_FILES[‘file’][‘name’]); if (copy($tmp_name, $save)) { $result = array( ‘status’ => 1,
‘info’ => ‘上传成功’,
);
} else {
$result = array(
‘status’ => 0,
‘info’ => ‘上传失败’,
);
}
} else {
$result = array(
‘status’ => 0,
‘info’ => ‘没有上传文件’,
);
}

echo json_encode($result);
[/code]

关于python进度条

最近在做一个应用程序,用Python写的。一边学习,一边实现自己想要的功能。做了好几天,才把登录做好。

现在,在做其中一个功能时,想实现进度条的效果。百度了老半天(英文太烂,比较少用stackoverflow),发现都找不到理想的demo,还有关于Python版本的问题,有时候找来的代码,执行不了,也是很头痛的。

最后,终于给我找到了一个用canvas画布实现的示例,貌似符合我的要求(网址:https://blog.csdn.net/li1615882553/article/details/79204072),废话不多说,直接上我修改后的示例代码
[code lang=”python”]from tkinter import *
import time

# 进度条
class Progress(object):
# 构造函数
def __init__(self, app=None):
# tk窗口
self.app = app
# 画布
self.canvas = Canvas(self.app, width=110, height=30)
# 成员变量
self.tips = StringVar()
# 调用画面内容
self.layout()

# 画布内容
def layout(self):
# 画布的位置
self.canvas.grid(row=0, column=0)
# 进度条的边框线
self.canvas.create_rectangle(10, 10, 100, 25, width=1, outline="blue")
# 文件提示
Label(self.app, textvariable=self.tips).grid(row=0, column=1)

# 更新状态
def update(self, percent=None):
# 进度条
line = self.canvas.create_rectangle(10, 10, 0, 25, width=0, fill="blue")
# 修改进度条长度
self.canvas.coords(line, [10, 10, percent, 25])
# 修改文字提示
self.tips.set(str(percent) + ‘%’)
# 刷新页面
self.app.update()

root = Tk()

p = Progress(root)
for i in range(25):
time.sleep(0.1)
p.update((i + 1) * 4)

mainloop()[/code]
 

时隔三年,我的博客又回来了

因为种种原因,我的博客闭关了三年。在这三年时间里,我换了工作,告别了以往的安逸。感觉自己对职业乃至人生,似乎有了目标和方向,虽然还不够明确。总有许多话想说,却又不知从何说起。

前段时间,腾讯出了校园计划,可以以很低的价格,搞到云主机,顿时又燃起了我对博客的情愫。购买云主机,配置服务器环境,域名备案,我又迎来了新的生活方式。昨晚本来还想早睡,搞搞Python,重新装装wordpress。不知不觉搞到早上5点多才睡,真的累啊!一大早又约了朋友去花城汇看电影,差点还起不来床。

看完电影,顺便去附近的图书馆找了找书,觉得自己该好好学学数据结构和算法。不求精通,起码能入个门,我正好也想换换环境,好好过面试那一关,找一个好的东家。不得不说,广州图书馆书真多,环境又好,又翻了一个方向的书柜,又找了10多本算法的书,挑了又挑,选了几个自己想看的。后来顺便去了省博物馆,CBD就是好了,各种优越资源扎堆,好了,今天的犊子扯到这里,不知道下次还能不能及时写博客了。。。