Administrator
06-02 11:00
openssh-server升级后无法使用ssh-rsa私钥进行登录解决方案:
往/etc/ssh/sshd_config文件的最后追加这一行
PubkeyAcceptedKeyTypes=+ssh-rsa
然后再重启ssh服务
Administrator
05-22 18:01
图片规格批量处理
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片规格批量压缩</title>
<script src="https://unpkg.com/jszip@3.10.1/dist/jszip.min.js"></script>
<style>
#machining_root {
padding-top: 20px;
text-align: center;
}
#machining_root input {
width: 150px;
}
#machining_root #compress {
width: 50px;
outline: none;
border-width: 1px;
border-style: none none solid none;
font-size: 16px;
text-align: center;
}
</style>
</head>
<body>
<div id="machining_root">
<div style="margin-bottom: 6px;">
<label for="compress">图片质量保留</label>
<input id="compress" type="text" value="90" />
<span>%</span>
</div>
<input type="file" accept="image/*" multiple="true" onchange="handlerFile(event)" />
<p class="filename"></p>
<p class="progress"></p>
</div>
</body>
<script type="text/javascript">
// QQ发图允许的最大图片像素数: 20249108: 3638 * 5566
// 但忘记怎么试出来的了
const maxRectSize = 2560 * 1440;
// 允许的最大宽度是4500
const maxRectWidth = 4500;
// 允许的最大高度是10000
const maxRectHeight = 9000;
/** @type {Array<HTMLInputElement>} */
const [compress, filename] = [document.querySelector("#machining_root #compress"), document.querySelector("#machining_root .filename")];
const progress = document.querySelector("#machining_root .progress");
async function handlerFile(e) {
const compressVal = parseFloat(compress.value);
if (isNaN(compressVal)) {
progress.innerText = `compress: ${compress.value} 不是一个有效的数字`;
return;
}
e.target.setAttribute("disabled", true);
/** @type {Array<File>} */
const files = Array.from(e.target.files);
if (files.length <= 0) {
e.target.removeAttribute("disabled");
return;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const zip = new JSZip();
for (let i = 0; i < files.length; i++) {
const file = files[i];
filename.innerText = "正在处理: " + file.name;
progress.innerText = `处理进度: ${i + 1}/${files.length}`;
const img = new Image();
img.src = URL.createObjectURL(file);
await new Promise(resolve => {
img.onload = () => {
resolve();
}
});
const [imgWidth, imgHeight] = getReasonableSize(getReasonablePixels(img));
canvas.width = imgWidth;
canvas.height = imgHeight;
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
const blobLink = await new Promise(resolve => {
canvas.toBlob(resolve, "image/jpeg", 0.01 * compressVal);
});
const fn = file.name.substring(0, file.name.lastIndexOf(".")) + ".jpg";
zip.file(fn, new File([blobLink], fn));
}
filename.innerText = "";
progress.innerText = "";
zip.generateAsync({ type: "blob" })
.then((zipBlob) => {
const aTag = document.createElement("a");
aTag.download = Date.now() + ".zip";
aTag.href = URL.createObjectURL(zipBlob);
aTag.click();
e.target.removeAttribute("disabled");
});
}
/**
* 获取不超过QQ发送图片像素上限的分辨率
* @param {HTMLImageElement} r
* @returns [number, number]
*/
function getReasonablePixels(r) {
let _p = 1;
if (r.width * r.height > maxRectSize) {
while ((r.width * _p) * (r.height * _p) > maxRectSize) {
_p -= 0.01;
}
return [r.width * _p, r.height * _p];
} else {
return [r.width, r.height];
}
}
/**
* 获取宽不超过4500,高不超过10000的分辨率
* @param {[number, number]} r
* @returns [number, number]
*/
function getReasonableSize(r) {
if (r[0] > maxRectWidth || r[1] > maxRectHeight) {
let _p = 1;
if (r[0] > r[1]) {
_p = (maxRectWidth / r[0]).toFixed(3);
r[0] = maxRectWidth;
r[1] = r[1] * _p;
} else {
_p = (maxRectHeight / r[1]).toFixed(3);
r[1] = maxRectHeight;
r[0] = r[0] * _p;
}
}
return r;
}
</script>
</html>
Administrator
04-19 18:37
preProcesser(/** @type {WechatMiniprogram.Canvas} */ canvas, /** @type { CanvasRenderingContext2D } */ ctx, img, /** @type {Number} */ index,) {
switch (imgOrientation[index]) {
case "up": {
canvas.width = imgWidth[index];
canvas.height = imgHeight[index];
ctx.drawImage(img, 0, 0, imgWidth[index], imgHeight[index]);
console.log(imgWidth[index], imgHeight[index]);
break;
}
case "right": {
// left和right方向需要交换width和height
[imgWidth[index], imgHeight[index]] = [imgHeight[index], imgWidth[index]];
canvas.width = imgWidth[index];
canvas.height = imgHeight[index];
ctx.translate(imgHeight[index] / 2, imgWidth[index] / 2)
ctx.drawImage(img, -imgHeight[index] / 2, -imgWidth[index] / 2, imgWidth[index], imgHeight[index])
ctx.rotate(90 * Math.PI / 180)
break;
}
case "down": {
canvas.width = imgWidth[index];
canvas.height = imgHeight[index];
ctx.translate(imgWidth[index] / 2, imgHeight[index] / 2)
ctx.drawImage(img, -imgWidth[index] / 2, -imgHeight[index] / 2, imgWidth[index], imgHeight[index])
ctx.rotate(180 * Math.PI / 180)
break;
}
case "left": {
// left和right方向需要交换width和height
[imgWidth[index], imgHeight[index]] = [imgHeight[index], imgWidth[index]];
canvas.width = imgWidth[index];
canvas.height = imgHeight[index];
ctx.translate(imgHeight[index] / 2, imgWidth[index] / 2)
ctx.drawImage(img, -imgHeight[index] / 2, -imgWidth[index] / 2, imgWidth[index], imgHeight[index])
ctx.rotate(270 * Math.PI / 180)
break;
}
}
},
小程序根据图片的orientation信息纠正图片方向
引用链接:ios手机竖屏拍照图片旋转90°问题解决方法
Administrator
01-26 14:53
canvas转存图片文件
<!DOCTYPE html>
<html lang="zh=CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas2png</title>
</head>
<body>
<canvas width="300" height="120"></canvas>
</body>
<script>
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
// 创建渐变色,指定渐变色覆盖范围
var lingrad = ctx.createLinearGradient(0, 0, 300, 120);
lingrad.addColorStop(0, '#FFCCCC');
lingrad.addColorStop(1, '#CCFFFF');
ctx.fillStyle = lingrad;
// 将渐变色画进canvas
ctx.fillRect(0, 0, 300, 120);
const dl = document.createElement("a");
dl.download = Date.now() + '.png';
canvas.toBlob(b => {
dl.href = URL.createObjectURL(b);
dl.click();
}, 'image/png');
</script>
</html>
引用: canvas2image
Administrator
07-29 18:19
微信小程序简单做一个盖章动画。
js:
this.setData({
showSeal: true,
})
this.animate(".seal", [
{opacity: 0, scale: [5, 5]},
{opacity: 1, scale: [1, 1], ease: 'ease'}
], 700, function () {
this.clearAnimation(".seal");
}.bind(this));
wxml:
<view class="seal">
<image wx:if="{{showSeal}}" mode="aspectFit" src="{{sealImg}}"></image>
</view>
Administrator
07-01 10:24
微信小程序中自定义tabbar,不要在其中使用cover-view和cover-image。
详情可见这个代码片段: https://developers.weixin.qq.com/s/XKUJpsmW71rO。
在模拟器中预览看起来很完美,但在真机调试时就会发现问题所在。