如何使用cropperjs中的数据使用ImageMagick执行调整大小和裁剪?
用户可以上传大图像并缩放/平移到裁剪。尝试使用blob,但它失去了太多的质量,并且经常出现问题。
Example来自以下数据:
Original Width: 1280
Original Height: 720
Width: 424.8717011756327
Height: 238.9903319112934
X: -155.17118867901692
Y: -1.4989251522088705
Scale: 23.82
试过这个,但它占用了错误的区域。还尝试缩放原始图像,但这对于服务器来说太大了。
convert orignial.jpg -resize "1280x720^" -gravity center -crop 424x238+-155+-1 +repage result.jpg
示例:https://jsfiddle.net/1knw3a5e/
JS代码:
$(function() {
var image = $('#crop-image');
var zoomSlider = document.getElementById('zoom-slider');
var canvasSize = null;
var pictureContainer = $('.picture-frame');
var maxPictureContainerWidth = parseFloat(pictureContainer.css('max-width')) || 450;
var maxPictureContainerHeight = parseFloat(pictureContainer.css('max-height')) || 350;
var isSliderInUse = false;
// Wall is in Cm, convert to Inches to work out pixel sizes at 300dpi
var wallWpx = (0.393700787 * pictureContainer.attr('data-width')) * 300; // data-width is the wall width in pixels
var wallHpx = (0.393700787 * pictureContainer.attr('data-height')) * 300; // data-height is the wall height in pixels
var sampleImageScaleFactor = (image.attr('width') / image.attr('original-width'));
var wallSize = {
width: wallWpx * sampleImageScaleFactor, // scaling the wall size corresponding the sample size
height: wallHpx * sampleImageScaleFactor,
originalWidth: pictureContainer.attr('data-width'),
originalHeight: pictureContainer.attr('data-height')
};
var wallAspectRatio = wallSize.originalWidth/wallSize.originalHeight;
var pictureContainerSizes = {
'width': maxPictureContainerWidth * (wallAspectRatio > 1 ? 1 : wallAspectRatio) ,
'height': maxPictureContainerHeight / (wallAspectRatio > 1 ? wallAspectRatio : 1)
};
pictureContainer.css(pictureContainerSizes).removeClass('hidden');
var zoomStep = 0.2;
var biggerSide = null;
var zoomModal = $('#modal-warning');
var handleZoomHold, handleZoomFired;
image.cropper({
zoom: 0.2,
guides: false,
cropBoxResizable: false,
cropBoxMovable: false,
//viewMode: 3,
dragMode: 'move',
left: 0,
top: 0,
//width: canvasSize.width,
//height: canvasSize.height,
//aspectRatio: 1,
toggleDragModeOnDblclick: false,
zoomOnTouch: true,
zoomOnWheel: true
});
// Event
image.on('built.cropper', function() {
image.cropper('setCropBoxData', {
left: 0,
top: 0,
width: pictureContainerSizes.width,
height: pictureContainerSizes.height
});
canvasSize = {
width: image.cropper('getCropBoxData').width,
height: image.cropper('getCropBoxData').height
};
biggerSide = canvasSize.width === image.cropper('getImageData').width ? 'width' : 'height';
var savedCropperSettings = {
sliceW: parseFloat($('input[name=sliceW]').val()),
sliceH: parseFloat($('input[name=sliceH]').val()),
sliceX: parseFloat($('input[name=sliceX]').val()),
sliceY: parseFloat($('input[name=sliceY]').val()),
scale: parseFloat($('input[name=scale]').val()) // saved adoptedZoomFactor
};
if (!savedCropperSettings.scale) {
return;
}
/* restoring saved settings */
image.cropper('zoomTo', canvasSize[biggerSide]/(wallSize[biggerSide]/savedCropperSettings.scale.toFixed(1)));
var cropboxData = image.cropper('getCropBoxData');
var scaleFactor = wallSize.originalHeight / cropboxData.height;
image.cropper('setCanvasData', {
left: savedCropperSettings.sliceX / scaleFactor + cropboxData.left,
top: savedCropperSettings.sliceY / scaleFactor + cropboxData.top
});
});
var adoptedZoomFactor = NaN;
var adoptedZoomElement = $('#adoptedZoom');
image.on('crop.cropper', function() {
var data = image.cropper('getData');
var canvasData = image.cropper('getCanvasData');
var cropboxData = image.cropper('getCropBoxData');
var scaleFactor = wallSize.originalHeight / cropboxData.height;
adoptedZoomFactor = parseFloat((wallSize[biggerSide] / data[biggerSide]).toFixed(2));
adoptedZoomElement.text(adoptedZoomFactor);
$('input[name=sliceW]').val(canvasData.width * scaleFactor);
$('input[name=sliceH]').val(canvasData.height * scaleFactor);
$('input[name=sliceX]').val((canvasData.left - cropboxData.left) * scaleFactor);
$('input[name=sliceY]').val(canvasData.top * scaleFactor);
$('input[name=scale]').val(adoptedZoomFactor);
});
});
在Safari或Firefox或Chrome中,我的Mac上的裁剪工具无法正常工作。它不尊重输入的比例值。总是出现scale = 1的结果。也许我做错了。
但是如果你想在ImageMagick中做到这一点,那么正确的方法是:
原版的:
Cropper Screen Snap:
裁剪器结果(尺寸320x180;静止比例= 1):
使用ImageMagick(尺寸640x360):
ww=320
hh=180
xx=40
yy=60
rotate=0
scale=2
scale=`convert xc: -format "%[fx:$scale*100]" info:`
convert barn.jpg -virtual-pixel white -define distort:viewport=${ww}x${hh}+${xx}+${yy} -filter point -distort SRT "$rotate" +repage -resize $scale% test.jpg
请注意,ImageMagick -distort SRT允许缩放,但缩放是在从视口进行裁剪之前完成的。所以我必须首先使用视口裁剪,然后以百分比形式添加-resize(作为scale = 2 - > scale = 200%)
我使用-distort SRT与视口裁剪的原因是,当xx和yy值为负时,它将允许偏移裁剪。你不能用简单的-crop做到这一点。
例如:
ww=320
hh=180
xx=-40
yy=-60
rotate=0
scale=1
scale=`convert xc: -format "%[fx:$scale*100]" info:`
convert barn.jpg -virtual-pixel white -define distort:viewport=${ww}x${hh}+${xx}+${yy} -filter point -distort SRT "$rotate" +repage -resize $scale% test2.jpg
如果您下载图像,您会看到它在顶部和右侧用白色填充,但仍然具有320x180的大小。
如果只在图像的范围内进行裁剪,那么可以使用-crop,Imagemagick命令将是:
ww=320
hh=180
xx=40
yy=60
rotate=0
scale=2
scale=`convert xc: -format "%[fx:$scale*100]" info:`
convert barn.jpg -crop ${ww}x${hh}+${xx}+${yy} +repage -resize $scale% test4.jpg
这会产生与原始视口裁剪相同的结果。
我只是成功地使用了getData
的数据而没有对结果进行任何数学计算。
var croppable = $('.croppable');
croppable.cropper({
autoCrop: true,
viewMode: 0,
background: false,
modal: true,
zoomable: true,
responsive: false,
crop: function(e) {
data = croppable.cropper('getData');
$('#extract_image_crop_x').val(data.x);
$('#extract_image_crop_y').val(data.y);
$('#extract_image_crop_width').val(data.width);
$('#extract_image_crop_height').val(data.height);
$('#extract_image_crop_rotate').val(data.rotate);
}
});