在这次项目中,我们需要这样一个应用场景。在手机里选择一张图片,并和明星图片合成。
- 难点1:ios下部分图片实际方向和预览方向不一直,需要先矫正方向
- 难点2:图片过大,实际用来合成的图片需要压缩
- 难点3:图片需要通过手指的滑动,进行位移,缩放
- 难点4:调整好图片位置后需要与指定图片和文字进行合成
选择图片后
document.getElementById("file").addEventListener("change", function () {
var file = this.files[0];
$(this).data('file', selfImg);
this.value = "";
//判断是否是图片类型
if (!/image\/\w+/.test(file.type)) {
alert("只能选择图片");
return false;
}
$("#mask-msg").html("上传中");
$(".loading").show();
//图片旋转
//图片压缩
//图片上传
})
复制代码
解决难点1: 页面head间引入
<script src="https://cdn.bootcss.com/exif-js/2.2.1/exif.min.js"></script>
复制代码
function rotate(file, callback) {
console.time('rotate');
console.log('loading-start');
window.EXIF.getData(file, function () {
window.EXIF.getAllTags(this);
var orientation = window.EXIF.getTag(this, 'Orientation');
console.log('loading-end');
// alert('loading-end');
console.log(orientation);
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.onload = function () {
var height = this.height, width = this.width;
var max = Math.max(height, width);
if (max > 800 && max < 1500) {
max /= 2;
height /= 2;
width /= 2;
}
if (max > 1500 && max < 2500) {
max /= 3;
height /= 3;
width /= 3;
}
if (max > 2500) {
max /= 4;
height /= 4;
width /= 4;
}
var angel = 0;
if (1 == orientation) {
angel = 0;
}
else if (6 == orientation) {
//6旋转90
angel = 90;
}
else if (3 == orientation) {
//3旋转180
angel = 180;
}
else if (8 == orientation) {
//8旋转90
angel = 270;
}
var canvas1 = document.createElement('canvas');
canvas1.setAttribute("height", max);
canvas1.setAttribute("width", max);
canvas1.style.width = '100%';
var ctx1 = canvas1.getContext('2d');
ctx1.translate(max / 2, max / 2);
ctx1.rotate(angel * Math.PI / 180);
ctx1.translate(-max / 2, -max / 2);
ctx1.drawImage(this, 0, 0, width, height);
var x = 0, y = 0, w = width, h = height;
if (orientation == 6 || orientation == 8) {
x = max - height;
y = max - width;
w = height;
h = width;
}
var imageData = ctx1.getImageData(x, y, w, h);
var canvas2 = document.createElement('canvas');
canvas2.setAttribute("height", h);
canvas2.setAttribute("width", w);
canvas2.style.width = '100%';
var ctx2 = canvas2.getContext('2d');
ctx2.putImageData(imageData, 0, 0);
var reImg = new Image();
reImg.src = canvas2.toDataURL("image/png");
reImg.onload = function () {
callback && callback(reImg);
console.timeEnd('rotate');
}
}
};
});
}
复制代码
解决难点2
function compress(src, callback) {
var img = new Image();
img.src = src;
img.onload = function () {
//等比缩放图片达到缩小文件的目的
var width = 1000;
if (img.height > width) {
var height = img.height * (width / img.width);
img.width = width;
img.height = height;
}
var canvas = document.createElement('canvas');
canvas.setAttribute('height', img.height);
canvas.setAttribute('width', img.width);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
var dataURL = canvas.toDataURL();
// var blod = this.dataURLtoBlob(dataURL);
callback && callback(dataURL);
};
}
复制代码
上传七牛 页面的head间引入
<script src="https://cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.js"></script>
复制代码
function dataURLtoBlob(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 });
}
function uploadFile(pic, cb) {
var url = "https://upload-z2.qbox.me";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST', url, true);
xmlHttp.setRequestHeader('X-Qiniu-Performance', 'true');
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
cb(qiniu.domain + JSON.parse(xmlHttp.responseText).key);
console.log(qiniu.domain + JSON.parse(xmlHttp.responseText).key);
}
};
var f = new FormData();
var blob = dataURLtoBlob(pic);
console.log(blob);
f.append('file', blob);
f.append('token', qiniu.uptoken);
xmlHttp.send(f);
}
复制代码
解决难点3 在页面head中需要引入
<script src="https://cdn.bootcss.com/hammer.js/2.0.8/hammer.min.js"></script>
复制代码
var selfImg = {
height: 0,
width: 0,
index: 0,
times: 2,
top: 0,
left: 0,
defaultHeight: parseInt($img.css('height')),
boxHeight: parseInt($box.css('height')),
boxWidth: parseInt($box.css('width'))
}, selfLogo = {
height: 0,
width: 0,
index: 0,
times: 2,
top: 0,
left: 0,
defaultHeight: parseInt($img.css('height')),
boxHeight: parseInt($box.css('height')),
boxWidth: parseInt($box.css('width'))
}, saveData = {};
var first = true;
var hammer = new Hammer(document.getElementById("self"));
hammer.get('pinch').set({ enable: true });
hammer.get('rotate').set({ enable: true });
hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammer.get('swipe').set({ direction: Hammer.DIRECTION_VERTICAL });
hammer.on('panstart', function (ev) {
createImg(selfImg, $img);
selfImg.imgX = ev.deltaX;
selfImg.imgY = ev.deltaY;
});
hammer.on('panmove', function (ev) {
if (first) {
selfImg.left -= selfImg.imgX - ev.deltaX;
selfImg.top -= selfImg.imgY - ev.deltaY;
moveImg($img, selfImg);
selfImg.imgX = ev.deltaX;
selfImg.imgY = ev.deltaY;
}
});
hammer.on('panend', function (ev) {
initImg(selfImg, $img);
});
hammer.on('pinchstart', function (ev) {
createImg(selfImg, $img);
});
hammer.on('pinchin', function (ev) {
if (selfImg.index % 2 == 0) {
pinchImg(ev, selfImg, $img);
}
selfImg.index++;
});
hammer.on('pinchout', function (ev) {
if (selfImg.index % 2 == 0) {
pinchImg(ev, selfImg, $img);
}
selfImg.index++;
});
hammer.on('pinchend', function (ev) {
initImg(selfImg, $img);
});
var hammerLogo = new Hammer(document.getElementById("self-logo"));
hammerLogo.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammerLogo.get('swipe').set({ direction: Hammer.DIRECTION_VERTICAL });
hammerLogo.on('panstart', function (ev) {
console.log(selfLogo);
createImg(selfLogo, $selfLogo);
first = false;
selfLogo.imgX = ev.deltaX;
selfLogo.imgY = ev.deltaY;
});
hammerLogo.on('panmove', function (ev) {
console.log('panmove');
selfLogo.left -= selfLogo.imgX - ev.deltaX;
selfLogo.top -= selfLogo.imgY - ev.deltaY;
moveImg($selfLogo, selfLogo);
selfLogo.imgX = ev.deltaX;
selfLogo.imgY = ev.deltaY;
});
hammerLogo.on('panend', function (ev) {
console.log(selfLogo);
first = true;
var change = false;
if (selfLogo.top < 0) {
selfLogo.top = 0;
change = true;
}
if (selfLogo.left < 0) {
selfLogo.left = 0;
change = true;
}
if (selfLogo.left + selfLogo.width > selfLogo.boxWidth) {
selfLogo.left = selfLogo.boxWidth - selfLogo.width;
change = true;
}
if (selfLogo.top + selfLogo.height > selfLogo.boxHeight * 0.74) {
selfLogo.top = selfLogo.boxHeight * 0.74 - selfLogo.height;
change = true;
}
if (change) {
moveImg($selfLogo, selfLogo);
}
});
//初始化图片对象
function initImg(_img, _node) {
_img.index = 0;
var change = false;
if (_img.top > 0) {
_img.top = 0;
change = true;
console.log(1);
}
if (_img.left > 0) {
_img.left = 0;
change = true;
console.log(2);
}
if (-_img.left >= _img.width - _img.boxWidth) {
_img.left = -(_img.width - _img.boxWidth);
change = true;
console.log(3);
}
if (_img.top < 0 && (-_img.top) + $footer.height() >= _img.height - _img.boxHeight) {
_img.top = -(_img.height - _img.boxHeight + $footer.height());
change = true;
console.log(4);
}
if (change) {
moveImg(_node, _img);
}
}
//创建图片
function createImg(_img, _node) {
_img.height = parseInt(_node.css('height'));
_img.width = parseInt(_node.css('width'));
}
//缩放图片
function pinchImg(ev, _img, _node) {
console.log(_img);
var obj = {};
obj.height = parseInt(_node.css('height'));
obj.width = parseInt(_node.css('width'));
if ((obj.width / obj.height) < (_img.boxWidth / _img.boxHeight)) {
var w = (_img.width * ev.scale);
if (w < _img.boxWidth) {
w = _img.boxWidth;
}
if (w > 2 * _img.boxWidth) {
w = 2 * _img.boxWidth;
}
_node.css("width", w + 'px');
} else {
var h = (_img.height * ev.scale);
if (h < _img.boxHeight) {
h = _img.boxHeight;
}
if (h > 2 * _img.boxHeight) {
h = 2 * _img.boxHeight;
}
_node.css("height", h + 'px');
}
_img.top += (obj.height - parseInt(_node.css('height'))) * ((ev.center.y - _img.top) / obj.height);
_img.left += (obj.width - parseInt(_node.css('width'))) * ((ev.center.x - _img.left) / obj.width);
moveImg(_node, _img);
createImg(_img, _node);
}
//移动图片
function moveImg(_node, _img) {
_node.css("transform", "translate3d(" + _img.left + "px," + _img.top + "px,0)");
}
复制代码
难点4
var image = new Image();
image.src = node.src;
image.onload = function () {
ctx.drawImage(image, _img.left, _img.top , $node.width(), $node.height() );
}
复制代码