JavaScript 이미지 처리 및 합성 총화

머리말
사진 처 리 는 이제 우리 생활 의 필수 가 되 었 으 니 여러분 도 이런 수요 가 많 을 것 입 니 다.실제 전단 업무 에서 도 그림 가공 과 처리 가 필요 한 항목 이 많다.지난 한 동안 회사 의 업무 수요 로 인해 저 는 이 면적 에서 건어물 에 지 쳤 습 니 다.몇 년 후에 이 시간 을 틈 타 일련의 글 로 정리 하여 여러분 과 공유 하 겠 습 니 다.여러분 의 노력 중의 전단 동화 에 시사 점 과 도움 을 주 셨 으 면 좋 겠 습 니 다.
본 시 리 즈 는 다음 과 같은 네 부분 으로 나 뉜 다.
  • 기본 유형의 이미지 처리 기술 의 크기 조정 과 재단;
  • 기초 유형 이미지 처리 기술 의 이미지 합성;
  • 기초 유형 이미지 처리 기술 의 문자 합성;
  • 알고리즘 유형 이미지 처리 기술;
  • 글 에서 저 는 실제 실천 에서 만난 구덩이 나 경험 을 많이 언급 할 것 입 니 다.건어물 이 가득 하 다 고 할 수 있 습 니 다~읽 을 수 있다 면 전단 이미지 처리 분야 에 대한 이 해 를 크게 향상 시 킬 수 있 을 것 입 니 다.관심 이 있 는 동 화 는 저 와 깊이 토론 할 수 있 습 니 다.본 고 는 벽돌 을 던 져 옥 을 끌 어 올 리 는 효 과 를 얻 고 전단 이 이미지 처리 에 있어 더 많은 가능성 을 가 질 수 있 기 를 바 랍 니 다.부족 한 점 이 있 으 면 양해 바 랍 니 다.
    이러한 축적 을 통 해 나 는 몇 가지 항목 에서 자주 사용 하 는 기능 을 봉인 했다.
    이미지 합성:Example Git 이미지 편집:Example Git 이미지 삭제:Example Git
    이런 낡은 방식 을 잔소리 한 후에 우 리 는 이륙 하기 시작 했다!
    우선,저 는 전단 이미지 처 리 를 두 가지 유형 으로 나 누 었 습 니 다.기본 유형 과 알고리즘 유형 입 니 다.
    기본 유형의 이미지 처리 기술:이미지 크기 조정,회전,테두리 추가,이미지 합성,퍼 즐 등 업 무 는 모두 기본 유형의 이미지 처리 에 속 합 니 다.그 구역 은 픽 셀 등급 의 알고리즘 을 사용 하지 않 고 그림 의 크기 와 위치 등 을 계산 하여 그림 을 만 드 는 데 있 습 니 다.예 를 들 어 자주 사용 하 는 스티커 기능:

    알고리즘 유형의 이미지 처리:이 유형의 이미지 처리 복잡 도가 비교적 높 고 픽 셀 등급 알고리즘 을 통 해 이미지 의 픽 셀 점RGBA채널 값 등 을 개조 하 는 것 이 특징 이다.예 를 들 어 우 리 는photshop또는 미 도 쇼 등 도 구 를 사용 하여 그림 에 대한 미 안/필터/흑백/파 기/모호 등 조작 을 하 는 것 이 특징 이다.이 유형의 중점 은 주로 알고리즘 과 성능 차원 에 있다.예 를 들 어 자주 사용 하 는 메 이 크 업 기능:

    이 시 리 즈 는 우선 기본 유형 처리 로 우리 의 여정 을 시작한다.기본 유형의 이미지 처 리 는 실제 프로젝트 에서 대량의 사용 장면 을 가지 는데 주로canvas의 능력 을 활용 하여 완성 하고 성능 과 호환성 문제 가 존재 하지 않 으 며 온라인 운행 기준 에 도달 할 수 있다.저 는 여기 서 기본 유형의 이미지 처 리 를 대체적으로 다음 과 같은 몇 가지 유형 으로 나 눌 수 있 습 니 다.이런 유형 은 일상적인 모든 업무 장면 을 커버 할 수 있 습 니 다.
  • 그림 의 크기 조정;
  • 그림 의 재단;
  • 그림 의 합성;
  • 그림 과 그림 의 합성,예 를 들 어 스티커,테두리,워 터 마크 등;그림 에 텍스트 추가 하기;그림 에 기초 기하학 적 도형 추가 하기;
    Tips:저 는 이 유형의 이미지 처리 장면 을 플러그 인 으로 봉 했 습 니 다.기본적으로 이 유형의 이미지 처리 수요 에 대응 할 수 있 습 니 다.GIT 주소(토론 을 환영 합 니 다).
    구체 적 인 기능 을 소개 하기 전에 그림 의 그리 기 는 그림 의 로드 에 완전히 의존 하기 때문에 먼저 선행 지식 을 알 아 보 겠 습 니 다.
    1.그림 의 크로스 필드
    먼저,그림 을 불 러 오고 그림 과 관련 된 크로스 도 메 인 문 제 를 그립 니 다.따라서 온라인 그림 이 라면 이미지 서버 에 크로스 도 메 인 헤드 를 설정 하고 전단 에 그림 을 불 러 오기 전에<img>태그crossOrigin*로 설정 해 야 합 니 다.그렇지 않 으 면 캔버스 에 그 릴 때 크로스 도 메 인 오 류 를 보고 합 니 다.
    Tips:여기 작은 구덩이 가 쌓 여 있어 서 여러분 과 공유 할 수 있 습 니 다.
  • crossOrigin은 엄격하게 설정 해 야 한다.온라인 그림 일 때 만 설정 할 수 있 고 로 컬 경로 나base64일 때 는 반드시 설정 할 수 없다.그렇지 않 으 면 일부 시스템 에서 오류 가 발생 하여 그림 로드 에 실패 할 수 있다.
  • 프로젝트 가 로 컬 패키지 환경 일 때 예 를 들 어App에 내 장 된 경우crossOrigin값 이 유효 하지 않 고webview의 안전 체 제 는 이 값 의 설정 여부 와 상 관 없 이 도 메 인 을 뛰 어 넘 는 오 류 를 초래 할 수 있다.해결 방법 은 모든 그림 을base64로 변환 해 야 정확하게 그 릴 수 있다 는 것 이다.
  • crossOrigin값 은 그림 을 불 러 오기 전에 설정 해 야 합 니 다.즉,<img>할당src전에 설정 해 야 합 니 다.그렇지 않 으 면 무효 입 니 다.
  • 2.그림 의 로 딩canvas의 그림 은 이미 불 러 온 그림 이 필요 하기 때문에 우 리 는 그 려 진 소재 그림 이 이미 불 러 온 것 인지 확인 해 야 합 니 다.따라서 우 리 는<img>onload사건 을 사용 해 야 합 니 다.html에 존재 하 는 그림 을 사용 하거나js으로 그림 대상 을 만 들 수 있 습 니 다.
    
    function loadImage(image, loader, error){
     //    image       ;
     let img = new Image();
     
     //        ,     crossOrigin   ;
     if(image.indexOf('http') == 0)img.crossOrigin = '*';
     img.onload = () => {
     loaded(img);
     
     //          ,    ;
     setTimeout(()=>{
      img = null;
     },1000);
     };
     img.onerror = () => {
     error('img load error');
     };
     img.src = image;
    }
    그림 로 딩 의 사전 지식 을 소개 한 후에 우 리 는 먼저 가장 간단 한 그림 처리-확대 와 재단 을 보 겠 습 니 다!
    Tips:여러분 이 본문 을 읽 을 때canvas에 대해 잘 모 르 면 해당 하 는API문 서 를 조회 하면 됩 니 다.본 고 는 더 이상canvas기초API에 대해 상세 하 게 설명 하지 않 습 니 다.
    그림 크기 조정
    그림 의 크기 조정 에서 가장 흔히 볼 수 있 는 장면 은 그림 의 압축 을 하 는 것 이다.그림 의 선명 함 을 확보 하 는 전제 에서 그림 의 사 이 즈 를 합 리 적 으로 줄 이면 그림 의 크기 를 크게 낮 출 수 있다.실제 응용 장면 에서 광범 위 한 용도 가 있다.예 를 들 어 사진 을 올 릴 때 사용자 가 자발적으로 올 린 사진 은 매우 큰 사이즈 일 수 있다.예 를 들 어 현재 핸드폰 으로 촬영 한 사진 의 사 이 즈 는 항상1920*2560의 사이즈 에 달 하고 크기 는 5M 를 초과 할 수 있다.프로젝트 에서 우 리 는 이렇게 큰 사 이 즈 를 사용 하지 않 아 도 될 것 이다.이때 그림 의 압축 은 로드 속 도 를 크게 최적화 시 키 고 대역 폭 을 절약 할 수 있다.
    1.canvas캔버스 를 새로 만 들 고 너비 와 높이 를 압축 할 사이즈 로 설정 합 니 다.
    이 캔버스 는 그림 의 크기 를 조정 한 사이즈 이기 때문에 그림 의 비례 가 변 하지 않도록 해 야 하 는 점 이 있 기 때문에 캔버스 의 너비 와 높이 를 계산 해 야 한다.
    
    let imgRatio = img.naturalWidth / img.naturalHeight;
    
    //         ;
    let cvs = document.createElement('canvas');
    
    //         ;
    let ctx = cvs.getContext('2d');
    cvs.width = 1000;
    cvs.height = cvs.width / imgRatio;
    2.그림 을 그 려 서 내 보 내기base64;
    여기 서 가장 많이 사용 하 는 방법 두 가 지 를 사용 합 니 다.ctx.drawImage(image, dx, dy, dw, dh):이 방법 은 사실 최대 9 개의 파 라 메 터 를 받 아들 여 압축 을 실현 할 수 있 습 니 다.그 중의 5 개의 파 라 메 터 를 사용 하면 됩 니 다.나머지 파 라 메 터 는 다른 부분 에서 사용 할 때 상세 하 게 설명 합 니 다.
    image:그 려 야 할 그림 원본 은 불 러 온HTMLImageElement,HTMLCanvasElement또는HTMLVideoElement를 받 아야 합 니 다.dx/dy:캔버스 왼쪽 상단 에 있 는 시작 점 좌 표를 그립 니 다.dw/dh:그림 의 너비 와 높이,너비 와 높이 비례 가 잠 겨 있 지 않 아 그림 을 변형 시 킬 수 있 습 니 다.cvs.toDataURL(type, quality):이 방법 은 캔버스 의 내용 을base64형식의 그림 으로 내 보 내 는 데 사용 되 며 2 개의 인 자 를 설정 할 수 있 습 니 다.
    type:그림 형식 입 니 다.일반적으로 사용 할 수 있 습 니 다image/png또는image/jpeg.그림 이 투명 하지 않 을 때 사용 하 는 것 을 권장 합 니 다jpeg.내 보 낼 그림 의 크기 를 많이 줄 일 수 있 습 니 다.quality:그림 품질,사용 가능0~1간 의 임 의 값;테스트 를 통 해 이 값 을0.9로 설정 할 때 적당 하 며 그림 파일 의 크기 를 효과적으로 줄 일 수 있 고 그림 의 선명 도 에 영향 을 주지 않 으 며 내 보 낸base64는 압축 된 그림 이기 도 합 니 다.
    Tips:여기 구덩이 가 있 습 니 다.jpg형식의 그림 을 내 보 내 려 면image/jpeg사용 해 야 합 니 다.image/jpg사용 할 수 없습니다.
    
    //                 ;
    ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
    
    //           base64    ;
    let b64 = cvs.toDataURL('image/jpeg', 0.9);
    
    3.다양한 형식의 그림 변환base64;
    우리 가 자주 사용 하 는 사진 업로드 기능 은 우리 가 사용 하 는 것 은 원생<input type="file">라벨 이다.이때 얻 은 것 은File형식의 그림 이다.그림 의 형식 이 각각 다 르 고 크기 가 크기 때문에 우 리 는 압축 처리 한 후에 사용 해 야 한다.
    사용FileReader:
    
    let file = e.files[0]; 
    if(window.FileReader) { 
     let fr = new FileReader(); 
     fr.onloadend = e => {
     let b64 = e.target.result;
     
     // b64  base64        ;
     }; 
     fr.readAsDataURL(file);
    }
    base64의 그림 을 아까canvas방식 으로 압축 처리 합 니 다.
    Tips:여기 작은 구덩이 가 있 는데 그림 의EXIF정보 중의 방향 값 이 그림 의 전시 에 영향 을 주 고IOS에 그림 의 너비 와 높이 가 그림 의 방향 과 일치 하지 않 는 문제 가 발생 하기 때문에 특수 처 리 를 하여 그림 의 방향 을 교정 해 야 한다.프로젝트:
    1.exif.js를 사용 하여 이미지 정보 중의Orientation속성 을 얻 을 수 있 고canvas의 회전 그리 기 를 이용 하여 교정 할 수 있다.
    2.여기canvasResize.js플러그 인 이 있 는데File부터base64까지 모든 문 제 를 해결 할 수 있 습 니 다.
    2.그림 의 재단
    실제 프로젝트 에서 그림 의 너비 와 높이 비례 가 다양 하기 때문에 전시 와 사용 은 일반적으로 비교적 고정된 비례 가 필요 하 다.이때 그림 을 우리 가 필요 로 하 는 너비 와 높이 비례 로 재단 해 야 한다.사용 하 는 방식 은 그림 의 크기 와 대체적으로 일치 하 는데 주로 조정drawImagedx, dy매개 변 수 를 통 해 이 루어 진다.원 리 는drawImage의 그리 기 시작 점(dx, dy)을 위로 이동 시 키 는 것 이다.이때canvas은 우리 가 원 하 는 재단 후의 사이즈 로 설정 되 었 기 때문에 캔버스 를 초과 한 부분 은 그리 지 않 고 재단 의 목적 을 달성 하 는 것 이다.유연 한 설정 값 을 통 해 각종 그림 재단 수 요 를 대체적으로 완성 할 수 있 습 니 다.간단 한 예제 그림(검은색 상 자 는 만 든 캔버스 의 크기 를 대표 합 니 다):

    이 곳 은600*800의 직사각형 그림 을 세로 로 가운데 로 자 르 는 것600*600의 정사각형 그림 을 예 로 들 어 기능 함수 로 간단하게 포장 합 니 다.
    
    //     :
    let b64 = cropImage(img, {
     width : 600,
     height : 600,
    });
    
    //     
    function cropImage(img, ops){
     //       ;
     let imgOriginWidth = img.naturalWidth,
     imgOriginHeight = img.naturalHeight;
     
     //      ,       ;
     let imgRatio = imgOriginWidth / imgOriginHeight;
     
     //         ,         ;
     let imgCropedWidth = ops.width || imgOriginWidth,
     imgCropedHeight = ops.height || imgOriginHeight;
     
     //              ,        ,          / 2;
     let dx = (imgCropedWidth - imgOriginWidth) / 2,
     dy = (imgCropedHeight - imgOriginHeight) / 2;
    
     //     ,             ;
     let cvs = document.createElement('canvas');
     let ctx = cvs.getContext('2d');
     cvs.width = imgCropedWidth;
     cvs.height = imgCropedHeight;
     
     //        ;
     ctx.drawImage(img, dx, dy, imgCropedWidth, imgCropedWidth / imgRatio);
     return cvs.toDataURL('image/jpeg', 0.9);
    }
    3.그림 의 회전
    그림 의 회전 원리 역시 그림 을 캔버스 에 그 려 회전 시 킨 후 내 보 내 는 것 이다.사실은canvasrotate방법 을 사용 했다.
    
    let cvs = document.createElement('canvas');
    let ctx = cvs.getContext('2d');
    
    //              ;
    ctx.translate(ctx.width/2, ctx.height/2);
    //     ;
    ctx.rotate = 90;
    //     ;
    ctx.drawImage(img);
    //           ;
    cvs.toDataURL();
    여기 서 비교적 특별한 부분 이 있 습 니 다.바로 여기 서 회전 하 는 것 은 캔버스 의 화판 부분 입 니 다.전체 캔버스 용기 가 아니 라 캔버스 용기 밖 에 그리 지 않 기 때문에 여기 서 그림 네 개의 각 이 잘 리 는 문제 가 발생 합 니 다.

    해결 방법 은:
    캔버스 용 기 를 확대 하여:

    위의 이 예 에서 그림 은 정사각형 이기 때문에 용기 의 너비 와 높이 를 1.5 배 확대 하면 그림 이 재단 되 지 않도록 보장 할 수 있 고 현실 의 그림 은 너비 와 높이 비례 가 정 해 지지 않 기 때문에 이 확대 계 수 는 동태 적 인 값 이다.
    Tips:우 리 는 화판 의 기 저 점 을 캔버스 중심 으로 이동 시 켰 기 때문에 그 릴 때 기 저 점 에 비해 조정dxdy해 야 합 니 다.
    
    //     ,    ;
    ...
    
    //      
    let iw = img.width, ih = img.height;
    let ir = iw > ih ? iw / ih : ih / iw;
    
    cvs.width = iw * ir * 1.5;
    cvs.height = ih * ir * 1.5;
    //              ;
    ctx.translate(cvs.width/2, cvs.height/2);
    //     ;
    ctx.rotate = 90;
    
    //     ;
    ctx.drawImage(img, -cvs.width/2, -cvs.height/2);
    
    //     ;
    ...
    총결산
    본 고 는 주로 전단 이미지 처리 의 선행 지식 을 소개 했다.
    사진 처리 기술 분류;
    기본 유형 이미지 처리 기술;알고리즘 유형 이미지 처리 기술;그림 의 크로스 필드;그림 불 러 오기;
    그리고 기본 유형의 이미지 처리 에서 가장 간단 한 두 가지 유형 을 설명 했다.
    그림 크기 조정;그림 의 재단;그림 의 회전;
    모두 가 이미 그림 의 처리 에 대해 대충 알 게 되 었 다 고 믿는다.다음 글 에서 우 리 는 기초 유형 중의 사진 합성 을 계속 깊이 연구 할 것 이 며,또한 각종 건어물 이 가득 차 서 이 루 다 헤 아 릴 수 없다.
    마지막 으로 어린이 신발 읽 어 주 셔 서 감사합니다. 어떤 건의 나 궁금 한 점 이 있 으 시 면 언제든지 저 와 토론 하 세 요.

    좋은 웹페이지 즐겨찾기