我的网站上有一个裁剪工具,用户可以上传图片并裁剪。
每当我上传手机拍摄的图片时,我都会遇到图像方向错误。
HTML
<div class="modal-body">
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "formAjax", enctype = "multipart/form-data", action = "/ProfilePicture/Crop" }))
{
@Html.AntiForgeryToken()
<label> Upload Photo: </label>
<label class="btn btn-default btn-file">
Browse @Html.TextBoxFor(ModelIndex => ModelIndex.ProfilePic.MyFile, new { id = "file", type = "file", style = "display: none;" })
</label>
<br /><br />
<div id="crop-image-area" style="display:none;">
<table border="0" cellpadding="0" cellspacing="5">
<tr>
<td>
<label>Preview: </label>
<div class="img-circle" style="width:100px;height:100px;overflow:hidden;margin-left:5px;">
<canvas id="preview"></canvas>
</div>
<br />
</td>
</tr>
<tr>
<td>
<label>Crop Here: </label>
<img src="" id="cropbox" style="display: none;">
</td>
</tr>
</table>
<br />
<input type="hidden" id="cropPointX" name="cropPointX" />
<input type="hidden" id="cropPointY" name="cropPointY" />
<input type="hidden" id="imageCropWidth" name="imageCropWidth" />
<input type="hidden" id="imageCropHeight" name="imageCropHeight" />
<span>
<input type="submit" id="btnCrop" class="btn btn-success" value="Crop" />
<label>
<img id="loader" src="~/Content/images/loading.gif" style="display:none;" />
</label>
</span>
</div>
}
</div>
JS
$(function() {
var jcrop_api;
$("#file").change(function() {
var reader = new FileReader();
reader.onload = function(e) {
$('#cropbox').show();
$('#cropbox').attr('src', e.target.result);
$('#cropbox').Jcrop({
onChange: updatePreview,
onSelect: getcroparea,
boxWidth: 400,
boxHeight: 400,
aspectRatio: 1,
bgOpacity: .4,
setSelect: [80, 45, 100, 100]
}, function() {
//first attempt
if (jcrop_api != null) {
jcrop_api.destroy();
}
//second attempt - even this does not work
$(".jcrop-holder").not(":last").remove();
jcrop_api = this;
});
$("#crop-image-area").hide();
$("#crop-image-area").fadeIn("slow");
}
reader.readAsDataURL($(this)[0].files[0]);
if ($('#cropbox').data('Jcrop')) {
$('#cropbox').data('Jcrop').destroy();
$('#cropbox').removeAttr('style');
}
});
function updatePreview(c) {
if (parseInt(c.w) > 0) {
var imageObj = jQuery("#cropbox")[0];
var canvas = jQuery("#preview")[0];
var context = canvas.getContext("2d");
context.beginPath();
context.arc(50, 50, 50, Math.PI * 4, 0, true);
context.clip();
context.closePath();
context.drawImage(imageObj, c.x, c.y, c.w, c.h, 0, 0, 100, 100);
}
};
function getcroparea(c) {
imageCropWidth = c.w;
imageCropHeight = c.h;
cropPointX = c.x;
cropPointY = c.y;
$('#cropPointX').val(Math.round(cropPointX))
$('#cropPointY').val(Math.round(cropPointY))
$('#imageCropWidth').val(Math.round(imageCropWidth))
$('#imageCropHeight').val(Math.round(imageCropHeight))
}
function destroyCrop() {
var jcropApi = $('#cropbox').data('Jcrop');
if (jcropApi !== undefined) {
jcropApi.destroy();
$('#cropbox').attr('style', "").attr("src", "");
}
}
function destroyPreview() {
$('#preview').removeAttr('src');
}
function cropImage() {
$("#loader").show();
$('#formAjax').ajaxSubmit({
type: 'POST',
success: function(result) {
$("#loader").hide();
$('#myProfilePicModal').modal('hide');
$("#crop-image-area").fadeOut("slow");
destroyCrop();
destroyPreview();
$("#alert-success").show();
$('#newImage').attr('src', 'data:image;base64,' + result.Photo);
$('.img-avatar').attr('src', 'data:image;base64,' + result.Avatar);
setTimeout(function() {
$("#alert-success").hide();
}, 5000);
},
error: function() {
$("#loader").hide();
$('#myProfilePicModal').modal('hide');
$("#crop-image-area").fadeOut("slow");
destroyCrop();
destroyPreview();
$("#alert-fail").show();
setTimeout(function() {
$("#alert-fail").hide();
}, 5000);
}
});
}
$("#btnCrop").on("click", function(e) {
e.preventDefault();
cropImage();
});
});
我不熟悉EXIF方向,请帮我在我的代码上实现它。
答案 0 :(得分:0)
我想您所说的是您想要从上传的图片中提取EXIF数据,然后旋转图片以使其始终处于某个位置。 对我而言,目前还不清楚图像会发生什么,例如我上传一张以横向模式制作的图片,而我的手机会将照片颠倒过来?当我上传使用portret模式拍摄的照片时会发生什么?因为我不知道这些信息,所以我无法为您创建完整的代码,但我可以帮助您继续前进。
以下是从客户端的图像中提取EXIF数据的片段。当有人将图像添加到输入文件时,这将触发。此代码段由用户制作:https://stackoverflow.com/users/893432/ali
function getOrientation(file, callback) {
var reader = new FileReader();
reader.onload = function(e) {
var view = new DataView(e.target.result);
if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
var length = view.byteLength, offset = 2;
while (offset < length) {
var marker = view.getUint16(offset, false);
offset += 2;
if (marker == 0xFFE1) {
if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
var little = view.getUint16(offset += 6, false) == 0x4949;
offset += view.getUint32(offset + 4, little);
var tags = view.getUint16(offset, little);
offset += 2;
for (var i = 0; i < tags; i++)
if (view.getUint16(offset + (i * 12), little) == 0x0112)
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
else if ((marker & 0xFF00) != 0xFF00) break;
else offset += view.getUint16(offset, false);
}
return callback(-1);
};
reader.readAsArrayBuffer(file);
}
// usage:
var input = document.getElementById('input');
input.onchange = function(e) {
getOrientation(input.files[0], function(orientation) {
alert('orientation: ' + orientation);
});
}
&#13;
<input id='input' type='file' />
&#13;
如果图片中包含EXIF数据,则会从图片中提取EXIF数据,您可以获得的响应值如下:
-2: not jpeg
-1: not defined
所以当它不是一个jpeg时,你会得到-2,当没有任何图片时你得到-1。如果它有效,您将获得图像中的一个响应,您必须使用jcrop旋转图像。
因此,假设您获得了代码8并且图像向右旋转了45度,您可以使用此代码将其向左旋转45度,这样您就知道它是直立的。
var jcp = $("#input").Jcrop('api');
jcp.ui.stage.setAngle(45).redraw();
据我所知,此代码段仅适用于jCrop 2+,您也可以尝试这样做:
$('#cropbox').Jcrop({
onChange: updatePreview,
onSelect: getcroparea,
boxWidth: 400,
boxHeight: 400,
setAngle: 45,
aspectRatio: 1,
bgOpacity: .4,
setSelect: [80, 45, 100, 100]
}
但我没有测试后者。
你最好的选择是:
这是另一种解决方案,它要求您稍微更改jCrop代码以允许旋转。 Make Jcrop tracker not rotate when cropping a rotated image