JavaScript 는 어떻게 이미지 처리 와 합성 을 실현 합 니까?

머리말:
사진 처 리 는 이제 우리 생활 의 필수 가 되 었 으 니 여러분 도 이런 수요 가 많 을 것 입 니 다.실제 전단 업무 에서 도 많은 항목 이 필요 하 다.
사진 가공 과 처리.
우선,저 는 전단 이미지 처 리 를 두 가지 유형 으로 나 누 었 습 니 다.기본 유형 과 알고리즘 유형 입 니 다.
  • 기본 유형의 이미지 처리 기술:이미지 크기 조정,회전,테두리 추가,이미지 합성,퍼 즐 등 업 무 는 모두 기본 유형의 이미지 처리 에 속 합 니 다.그 구역 은 픽 셀 등급 의 알고리즘 을 사용 하지 않 고 그림 의 크기 와 위치 등 을 계산 하여 그림 을 개조 하 는 데 있 습 니 다.예 를 들 어 자주 사용 하 는 스티커 기능:
  • 알고리즘 유형의 이미지 처리:이 유형의 이미지 처리 복잡 도가 비교적 높 고 픽 셀 등급 알고리즘 을 통 해 이미지 의 픽 셀 점 을 RGBA 채널 값 등 으로 개조 하 는 것 이 특징 이다.예 를 들 어 우 리 는 photshop 이나 미 투 쇼 등 도 구 를 사용 하여 이미지 에 대한 미 안/필터/흑백/파 기/모호 등 조작,이 유형의 중점 은 주로 알고리즘 과 성능 차원 에 있다.예 를 들 어 자주 사용 하 는 메 이 크 업 기능:
  • 이러한 축적 을 통 해 나 는 몇 가지 항목 에서 자주 사용 하 는 기능 을 봉인 했다.
  • 사진 합성:ExampleGit
  • 사진 재단:ExampleGit
  • 인상 파기:ExampleGit
  • 이 시 리 즈 는 우선 기본 유형 처리 로 우리 의 여정 을 시작한다.기본 유형의 이미지 처 리 는 실제 프로젝트 에서 대량의 사용 장면 을 가지 는데 주로 canvas 의 능력 을 활용 하여 완성 되 고 성능 과 호환성 문제 가 존재 하지 않 으 며 온라인 운행 기준 에 도달 할 수 있다.저 는 여기 서 기본 유형의 이미지 처 리 를 대체적으로 다음 과 같은 몇 가지 유형 으로 나 눌 수 있 습 니 다.이런 유형 은 일상적인 모든 업무 장면 을 커버 할 수 있 습 니 다.
  • 그림 의 크기 조정;
  • 그림 의 재단;
  • 그림 의 합성;
  • 그림 과 그림 의 합성,예 를 들 어 스티커,테두리,워 터 마크 등;
  • 그림 에 텍스트 추가 하기;
  • 그림 에 기초 기하학 적 도형 을 추가 합 니 다.
  • Tips:저 는 이 유형의 이미지 처리 장면 을 플러그 인 으로 봉 했 습 니 다.기본적으로 이 유형의 이미지 처리 수요 에 대응 할 수 있 습 니 다.GIT 주소(연 구 를 환영 합 니 다)
    구체 적 인 기능 을 소개 하기 전에 그림 의 그리 기 는 그림 의 로드 에 완전히 의존 하기 때문에 먼저 선행 지식 을 알 아 보 겠 습 니 다.
    1.그림 의 크로스 필드
    먼저,그림 을 불 러 오고 그림 과 관련 된 크로스 도 메 인 문 제 를 그립 니 다.따라서 온라인 그림 이 라면 이미지 서버 에 크로스 도 메 인 헤드 를 설정 하고 전단 에 그림 을 불 러 오기 전에태그 의 crossOrigin 을*로 설정 해 야 합 니 다.그렇지 않 으 면 캔버스 에 그 릴 때 크로스 도 메 인 오 류 를 보고 합 니 다.
    Tips:여기 작은 구덩이 가 쌓 여 있어 서 여러분 과 공유 할 수 있 습 니 다.
    1.crossOrigin 은 엄격하게 설정 해 야 합 니 다.온라인 그림 일 때 만 설정 할 수 있 고 로 컬 경로 나 base 64 일 때 설정 할 수 없습니다.그렇지 않 으 면 일부 시스템 에서 오류 가 발생 하여 그림 로드 에 실패 할 수 있 습 니 다.
    2.프로젝트 가 로 컬 패키지 환경 일 때 예 를 들 어 App 에 내 장 될 때 crossOrigin 값 이 잘못 되 고 webview 의 보안 체 제 는 이 값 의 설정 여부 와 상 관 없 이 도 메 인 간 의 오 류 를 보고 할 수 있 습 니 다.해결 방법 은 모든 그림 을 base 64 로 변환 해 야 정확하게 그 릴 수 있 습 니 다.
    3.crossOrigin 값 은 그림 을 불 러 오기 전에 설정 해 야 합 니 다.즉,할당 src 전에 설정 해 야 합 니 다.그렇지 않 으 면 유효 하지 않 습 니 다.
    2.그림 의 로 딩
    canvas 의 그리 기 에 필요 한 것 은 이미 불 러 온 그림 입 니 다.그 려 진 소재 그림 이 불 러 온 것 인지 확인 해 야 합 니 다.따라서의 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.그림 을 그린 다음 base 64 로 내 보 내기;
    여기 서 가장 많이 사용 하 는 방법 두 가 지 를 사용 합 니 다.
  • ctx.drawImage(image,dx,dy,dw,dh):이 방법 은 사실 최대 9 개의 인 자 를 받 아들 여 압축 을 실현 할 수 있 습 니 다.그 중의 5 개의 인 자 를 사용 하면 됩 니 다.나머지 인 자 는 다른 부분 에서 사용 할 때 상세 하 게 설명 합 니 다.
  • image:그 려 야 할 그림 원본 은 불 러 온 HTML ImageElement,HTML CanvasElement 또는 HTML VideoElement 를 받 아야 합 니 다.
  • dx/dy:캔버스 왼쪽 상단 에 있 는 시작 점 좌 표를 그립 니 다.
  • dw/dh:그 려 진 너비 와 높이,너비 와 높이 비례 가 잠 겨 있 지 않 아 그림 을 변형 시 킬 수 있 습 니 다.
  • cvs.toDataURL(type,quality):이 방법 은 캔버스 의 내용 을 base 64 형식의 그림 으로 내 보 내 는 데 사용 되 며 2 개의 인 자 를 설정 할 수 있 습 니 다.
  • type:그림 형식 입 니 다.보통 image/png 또는 image/jpeg 를 사용 할 수 있 습 니 다.그림 이 투명 하지 않 을 때 jpeg 를 사용 하 는 것 을 권장 합 니 다.내 보 낼 그림 의 크기 를 많이 줄 일 수 있 습 니 다.
  • quality:그림 품질,0~1 사이 의 임 의 값 을 사용 할 수 있 습 니 다.테스트 를 통 해 이 값 을 0.9 로 설정 하 는 것 이 적당 하고 그림 파일 의 크기 를 효과적으로 줄 일 수 있 으 며 그림 의 선명 도 에 영향 을 주지 않 습 니 다.내 보 낸 base 64 는 압축 된 그림 입 니 다.
  • Tips:여기에 구덩이 가 있 습 니 다.jpg 형식의 그림 을 내 보 내 려 면 image/jpeg 를 사용 해 야 합 니 다.image/jpg 를 사용 할 수 없습니다.
    //크기 조정 후의 캔버스 에 원 그림 등 비율 을 그립 니 다.
    ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
    //그 려 진 그림 을 base 64 형식 으로 내 보 냅 니 다.
    let b64 = cvs.toDataURL('image/jpeg', 0.9);
    3.다양한 형식의 그림 을 base 64 로 변환 합 니 다.
    우리 가 자주 사용 하 는 그림 업로드 기능 은 원생 의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);
    }
    base 64 의 그림 을 방금 canvas 방식 으로 압축 처리 하기;
    Tips:여기 작은 구덩이 가 있 는데 그림 의 EXIF 정보 중의 방향 값 이 그림 의 전시 에 영향 을 주 고 IOS 에서 그림 의 너비 와 높이 가 그림 의 방향 과 일치 하지 않 는 문제 가 발생 하기 때문에 특수 처 리 를 하여 그림 의 방향 을 교정 해 야 한다.프로젝트:
    1.exif.js 를 사용 하여 그림 정보 중의 Orientation 속성 을 얻 고 canvas 의 회전 그리 기 를 이용 하여 교정 할 수 있 습 니 다.
    2.여기 canvasResize.js 플러그 인 이 있 습 니 다.File 에서 base 64 까지 의 모든 문 제 를 해결 할 수 있 습 니 다.
    2.그림 의 재단
    실제 프로젝트 에서 그림 의 너비 와 높이 비례 가 다양 하기 때문에 전시 와 사용 은 일반적으로 비교적 고정된 비례 가 필요 하 다.이때 그림 을 우리 가 필요 로 하 는 너비 와 높이 비례 로 재단 해 야 한다.사용 하 는 방식 은 그림 의 크기 와 대체적으로 일치 하 는데 주로 drawImage 의 dx,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.그림 의 회전
    그림 의 회전 원리 역시 그림 을 캔버스 에 그 려 회전 시 킨 후 내 보 내 는 것 이다.사실 canvas 의 rotate 방법 을 사 용 했 습 니 다.
    
    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:우 리 는 화판 의 기 저 점 을 캔버스 중심 으로 이동 시 켰 기 때문에 그 릴 때 기 저 점 에 비해 dx 와 dy 를 조정 해 야 합 니 다.
    
    //     ,    ;
    ...
    
    //      
    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);
    
    //     ;
    ...
    총결산
    본 고 는 주로 전단 이미지 처리 의 선행 지식 을 소개 했다.
    사진 처리 기술 분류;
  • 기초 유형 이미지 처리 기술;
  • 알고리즘 유형 이미지 처리 기술;
  • 그림 의 크로스 필드;
  • 그림 의 불 러 오기;
  • 그리고 기본 유형의 이미지 처리 에서 가장 간단 한 두 가지 유형 을 설명 했다.
  • 그림 의 크기 조정;
  • 그림 의 재단;
  • 그림 의 회전;
  • 이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기