업로드하기 전에 브라우저에서 이미지 자르기
Jcrop과 같이 내가 찾은 많은 라이브러리는 실제로 자르기를 수행하지 않고 이미지 자르기 UI 만 생성합니다. 그런 다음 실제 자르기를 수행하는 서버에 따라 다릅니다.
서버 측 코드를 사용하지 않고 HTML5 기능 을 사용 하여 이미지 자르기 클라이언트 측 을 어떻게 만들 수 있습니까 ?
그렇다면 몇 가지 예나 힌트가 있습니까?
예, 할 수 있습니다.
앵커 태그의 새로운 html5 "다운로드"속성을 기반으로합니다.
흐름은 다음과 같아야합니다.
- 이미지로드
- 자르기 경계가 지정된 캔버스에 이미지를 그립니다.
- 캔버스에서 이미지 데이터를 가져 와서
href
DOM의 앵커 태그에 대한 속성으로 만듭니다. - 다운로드 속성 (
download="desired-file-name"
)을 해당a
요소에 추가합니다 . 사용자는 "다운로드 링크"를 클릭하기 만하면 이미지가 자신의 PC로 다운로드됩니다.
기회가되면 데모로 돌아 올게요.
업데이트는
여기 라이브 데모 내가 약속. 그것은 소요 jsfiddle 로고를 각각 마진의 5px 작물.
코드는 다음과 같습니다.
var img = new Image();
img.onload = function(){
var cropMarginWidth = 5,
canvas = $('<canvas/>')
.attr({
width: img.width - 2 * cropMarginWidth,
height: img.height - 2 * cropMarginWidth
})
.hide()
.appendTo('body'),
ctx = canvas.get(0).getContext('2d'),
a = $('<a download="cropped-image" title="click to download the image" />'),
cropCoords = {
topLeft : {
x : cropMarginWidth,
y : cropMarginWidth
},
bottomRight :{
x : img.width - cropMarginWidth,
y : img.height - cropMarginWidth
}
};
ctx.drawImage(img, cropCoords.topLeft.x, cropCoords.topLeft.y, cropCoords.bottomRight.x, cropCoords.bottomRight.y, 0, 0, img.width, img.height);
var base64ImageData = canvas.get(0).toDataURL();
a
.attr('href', base64ImageData)
.text('cropped image')
.appendTo('body');
a
.clone()
.attr('href', img.src)
.text('original image')
.attr('download','original-image')
.appendTo('body');
canvas.remove();
}
img.src = 'some-image-src';
업데이트 II
언급하는 것을 잊었습니다. 물론 단점이 있습니다. :(.
이미지에도 적용되는 동일 출처 정책으로 인해 이미지의 데이터에 액세스하려는 경우 (캔버스 방법을 통해 toDataUrl
)
여전히 필요합니다. 도메인에서 호스팅 된 것처럼 이미지를 제공하는 서버 측 프록시.
업데이트 III (보안상의 이유로) 이에 대한 라이브 데모를 제공 할 수 없지만 다음은 동일 출처 정책을 해결하는 PHP 샘플 코드입니다.
파일 proxy.php
:
$imgData = getimagesize($_GET['img']);
header("Content-type: " . $imgData['mime']);
echo file_get_contents($_GET['img']);
이렇게하면 원본에서 직접 외부 이미지를로드하는 대신
img.src = 'http://some-domain.com/imagefile.png';
프록시를 통해로드 할 수 있습니다.
img.src = 'proxy.php?img=' + encodeURIComponent('http://some-domain.com/imagefile.png');
다음은 이미지 데이터 (base64)를 실제 이미지에 저장하기위한 샘플 PHP 코드입니다.
파일 save-image.php
:
$data = preg_replace('/data:image\/(png|jpg|jpeg|gif|bmp);base64/','',$_POST['data']);
$data = base64_decode($data);
$img = imagecreatefromstring($data);
$path = 'path-to-saved-images/';
// generate random name
$name = substr(md5(time()),10);
$ext = 'png';
$imageName = $path.$name.'.'.$ext;
// write the image to disk
imagepng($img, $imageName);
imagedestroy($img);
// return the image path
echo $imageName;
그러면이 파일에 이미지 데이터를 게시하기 만하면 이미지가 디스크에 저장되고 기존 이미지 파일 이름이 반환됩니다.
물론이 모든 것이 조금 복잡하게 느껴질 수도 있지만, 여러분이 달성하려는 것이 가능하다는 것을 보여 드리고 싶었습니다.
The Pixastic library does exactly what you want. However, it will only work on browsers that have canvas support. For those older browsers, you'll either need to:
- supply a server-side fallback, or
- tell the user that you're very sorry, but he'll need to get a more modern browser.
Of course, option #2 isn't very user-friendly. However, if your intent is to provide a pure client-only tool and/or you can't support a fallback back-end cropper (e.g. maybe you're writing a browser extension or offline Chrome app, or maybe you can't afford a decent hosting provider that provides image manipulation libraries), then it's probably fair to limit your user base to modern browsers.
EDIT: If you don't want to learn Pixastic, I have added a very simple cropper on jsFiddle here. It should be possible to modify and integrate and use the drawCroppedImage
function with Jcrop.
#change-avatar-file
is a file input #change-avatar-file
is a img tag (the target of jcrop) The "key" is FR.onloadend Event https://developer.mozilla.org/en-US/docs/Web/API/FileReader
$('#change-avatar-file').change(function(){
var currentImg;
if ( this.files && this.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
$('#avatar-change-img').attr( "src", e.target.result );
currentImg = e.target.result;
};
FR.readAsDataURL( this.files[0] );
FR.onloadend = function(e){
//console.log( $('#avatar-change-img').attr( "src"));
var jcrop_api;
$('#avatar-change-img').Jcrop({
bgFade: true,
bgOpacity: .2,
setSelect: [ 60, 70, 540, 330 ]
},function(){
jcrop_api = this;
});
}
}
});
If you will still use JCrop, you will need only this php functions to crop the file:
$img_src = imagecreatefromjpeg($src);
$img_dest = imagecreatetruecolor($new_w,$new_h);
imagecopyresampled($img_dest,$img_src,0,0,$x,$y,$new_w,$new_h,$w,$h);
imagejpeg($img_dest,$dest);
client side:
jQuery(function($){
$('#target').Jcrop({
onChange: showCoords,
onSelect: showCoords,
onRelease: clearCoords
});
});
var x,y,w,h; //these variables are necessary to crop
function showCoords(c)
{
x = c.x;
y = c.y;
w = c.w;
h = c.h;
};
function clearCoords()
{
x=y=w=h=0;
}
참고URL : https://stackoverflow.com/questions/12728188/cropping-images-in-the-browser-before-the-upload
'developer tip' 카테고리의 다른 글
HTML5 용 오픈 그래프 유효성 검사 (0) | 2020.12.13 |
---|---|
jQuery가 포함 된 HTML5-e.offsetX가 Firefox에서 정의되지 않음 (0) | 2020.12.13 |
CSS 변환이 인라인 요소에서 작동하지 않습니다. (0) | 2020.12.13 |
직렬화 가능한 Python 객체의 JSON 인코딩 동작을 변경하는 방법은 무엇입니까? (0) | 2020.12.13 |
adb에서 인식되지 않는 Android 기기 (0) | 2020.12.13 |