본문 바로가기

WebGL

WebGL Fundamentals > Cross Origin Images

https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html

 

WebGL - Cross Origin Images

Using images across domains

webglfundamentals.org

https://github.com/Myoungmin/WebGL_Fundamentals

 

GitHub - Myoungmin/WebGL_Fundamentals: WebGL 학습 프로젝트

WebGL 학습 프로젝트. Contribute to Myoungmin/WebGL_Fundamentals development by creating an account on GitHub.

github.com

 

 

WebGL - Cross Origin Images

WebGL에서는 텍스처로 사용하기 위해 이미지를 다운로드한 다음 GPU에 업로드하는 것이 일반적이다.

일반적인 이미지를 다운로드 방법

// 텍스처 정보 { width: w, height: h, texture: tex } 생성합니다.
// 텍스처는 1x1 픽셀로 시작하고 이미지가 로드되면 업데이트됩니다.
function loadImageAndCreateTextureInfo(url) {
  var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  // 텍스처를 1x1 파란 픽셀로 채우기
  gl.texImage2D(
    gl.TEXTURE_2D,
    0,
    gl.RGBA,
    1,
    1,
    0,
    gl.RGBA,
    gl.UNSIGNED_BYTE,
    new Uint8Array([0, 0, 255, 255])
  );
 
  // 모든 이미지가 2의 거듭제곱이 아니라고 가정
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
 
  var textureInfo = {
    width: 1,   // 로드될 때까지 크기를 모름
    height: 1,
    texture: tex,
  };
  var img = new Image();
  img.addEventListener('load', function() {
    textureInfo.width = img.width;
    textureInfo.height = img.height;
 
    gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
  });
  img.src = url;
 
  return textureInfo;
}

 

문제는 이미지에 개인 데이터가 있을 수 있다는 것이다.

웹 페이지에는 페이지를 직접 제어하지 않는 광고와 기타 요소들이 있으므로 브라우저는 이러한 개인 이미지를 볼 수 없도록 해야한다.

 

이미지가 브라우저에 표시되더라도 스크립트는 이미지 내부의 데이터를 볼 수 없기 때문에 <img src="private.jpg">만 사용하는 것은 괜찮다.

 

하지만 다른 도메인에서 가져와 그린 이미지라면 브라우저는 캔버스를 오염되었다고 표시하고 ctx.getImageData를 호출할 때 보안 오류가 발생한다.

 

WebGL은 더 나아가 같은 도메인이 아닌 모든 이미지를 금지한다.

 

 

 

CORS 입력하여 다른 도메인 이미지를 가져오기

CORS(Cross Origin Resource Sharing)는 웹 페이지에 이미지 사용 권한을 이미지 서버에 요청하는 방법이다.

 

이를 위해 crossOrigin 속성을 특정값으로 설정한 다음, 브라우저가 서버에서 이미지를 가져오려고 시도할 때, 동일한 도메인이 아니라면, 브라우저는 CORS 권한을 요청한다.

 

img.crossOrigin = "";   // CORS 권한 요청

 

crossOrigin에 설정할 수 있는 값 3가지

  1. "권한을 요청하지 않음"을 의미하는 기본값인 "undefined"
  2. "권한을 요청하지만 추가 정보를 보내지 않음"을 의미하는 "anonymous"
  3. "서버가 권한을 부여할지 말지 결정하기 위해 살펴보는 쿠키와 기타 정보 전송"을 의미하는 "use-credentials"

그 외 다른 값으로 crossOrigin을 설정하면 anonymous로 설정한 것과 같다.

로드하려는 이미지가 동일한 origin에 있는지 확인하고, 다르다면 crossOrigin 속성을 설정하는 함수

function requestCORSIfNotSameOrigin(img, url) {
  if ((new URL(url, window.location.href)).origin !== window.location.origin) {
    img.crossOrigin = "";
  }
}

 

  • 권한을 요청한다고 해서 권한이 부여되는 것은 아니다.
  • Github page, flickr.com, imgur.com 등은 권한을 부여하지만, 대부분의 웹 사이트는 그렇지 않다.
  • 권한을 부여하기 위해 서버는 이미지를 보낼 때 특정 헤더를 보낸다.
  • 만약 다른 도메인의 이미지라면 crossOrigin 속성을 설정해야 하고 그렇지 않으면 서버가 올바른 헤더를 보내도 이미지를 사용할 수 없다.

 

 

 

 

 

 

https://myoungmin.github.io/WebGL_Fundamentals/

 

WebGL_Fundamentals

WebGL이란? WebGL은 Web Graphics Library의 약자로 웹상에서 2D 및 3D 그래픽을 렌더링하기 위한 로우 레벨 Javascript API. 학습내용 블로그 정리

myoungmin.github.io