캔버스 요소에서 요소를 그린 후 불투명도 (알파, 투명도)를 변경하는 방법은 무엇입니까?


196

HTML5 <canvas>요소를 사용하여 이미지 파일 (PNG, JPEG 등)을로드하고 캔버스에 완전히 투명하게 그린 다음 페이드 인합니다. 이미지를로드하고 이미지를 그리는 방법을 알아 냈습니다. 캔버스, 그러나 그려지는 불투명도를 변경하는 방법을 모르겠습니다.

지금까지 내가 작성한 코드는 다음과 같습니다.

var canvas = document.getElementById('myCanvas');

if (canvas.getContext)
{
    var c           = canvas.getContext('2d');
    c.globalAlpha   = 0;

    var img     = new Image();
    img.onload  = function() {
        c.drawImage(img, 0, 0);
    }
    img.src     = 'image.jpg';
}

누군가가 설정하는 속성이나 불투명도를 변경하는 호출하는 함수와 같은 올바른 방향을 알려주시겠습니까?

답변:


307

필자는 기본 도형을 사용하여 채우기 및 획을 설정할 수있는 경우이 질문에 대한 답을 찾고 있습니다 (명확하게하기 위해 불투명도로 도형을 그리는 방법과 같이 사용자 정의 불투명도로 이미지를 그릴 수 있기를 원합니다) 알파로 색상을 지정하여 투명도를 정의합니다. 내가 지금까지 결론을 내린 한, 이것은 이미지 드로잉에 영향을 미치지 않는 것 같습니다.

//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";

나는 globalCompositeOperation이미지로 작품 을 설정한다고 결론 지었다 .

//works with images
ctx.globalCompositeOperation = "lighter";

이미지를 색조하고 쉽게 투명하게 만들 수 있도록 색상을 설정하는 세 번째 방법이 있는지 궁금합니다.

편집하다:

더 파고 난 후에 이미지 globalAlpha를 그리기 전에 매개 변수 를 설정하여 이미지의 투명도를 설정할 수 있다고 결론을 내 렸습니다 .

//works with images
ctx.globalAlpha = 0.5

시간이 지남에 따라 페이딩 효과를 얻으려면 알파 값을 변경하는 일종의 루프가 필요합니다. 이는 매우 쉽습니다.이를 달성하는 한 가지 방법은 setTimeout함수입니다. 알파를 변경하는 루프를 만드는 방법을 찾으십시오. 시각.


7
globalAlpha는 완벽하게 작동합니다. whatwg.org/specs/web-apps/current-work/multipage/…의
Aleris

42
정확하게 말하면, 속성 canvas을 갖는 요소가 globalAlpha아니라 캔버스에서 얻는 컨텍스트입니다.
Steve Blackwell

8
ctx.save () 및 ctx.restore ()에 대한 Ian의 의견은 globalAlpha가 나머지 캔버스에 영향을 미치지 않도록합니다.
Arosboro

1
캔버스에 그려진 불투명도를 제어하는 ​​것이 아니라 이미지가 그려진 후 전체 캔버스 자체의 불투명도를 한 번만 제어하는 ​​목적으로 사용하는 것이 더 간단하고 여전히 유용합니다. 일반적인 CSS / style 메소드를 사용 하여이 작업을 수행하십시오 (canvaselement.style.opacity = '0.3'; 등) CSS3 이후에는 루프를 완전히 사용하지 않고 브라우저가 페이딩을 대신 처리하도록 할 수도 있습니다 (전환과 같은 것 : NNNms 불투명도 완화) 또는 페이딩을 "애니메이션"합니다.
Chuck Kollars

1
불행히도 canvas2d.fillStyle = "rgba(255, 255, 255, 0.5)";작동하지 않습니다. 값은 16 진수 여야합니다.
WebWanderer

113

다음을 사용하는 간단한 코드 예 globalAlpha:

ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();

img로드 해야하는 경우 :

var img = new Image();
img.onload = function() {
    ctx.save();
    ctx.globalAlpha = 0.4;
    ctx.drawImage(img, x, y);
    ctx.restore()
};
img.src = "http://...";

노트:

  • 이미지가 이미 캐시에있는 경우에도 모든 플랫폼에서 핸들러가 호출 'src'되도록 마지막을 설정하십시오 onload.

  • 변경 사항을 globalAlphaa save와 같은 것 restore(실제로 많이 사용) 사이에 래핑하여 특히 드로잉 코드 비트가 이벤트에서 호출 될 때 다른 곳에서 설정을 방해하지 않도록합니다.


globalAlpha는 캔버스의 모든 이미지 나 그림을 흐리게합니다.
Grumpy

6
@Grumpy-아니요, globalAlpha아무 것도 흐리게하지 않습니다. 그것은 모든 후속 드로잉에 대해 알파를 설정합니다 (이미 그려진 그림은 변경하지 않습니다). 그래서 예제 코드에서 save와를 감싸서 restore적용 대상을 제한하는 이유입니다.
Ian

ctx.restore ()가 globalAlpha를 복원하는지 확실하지 않습니다. 또한 마지막에 (최소 버전의 Chrome에서는해야했습니다) ctx.globalAlpha = 1;
Sean

1
@Sean-확실하지 않은 경우 확인해야합니다. 그것은 이제 모든 플랫폼에서 작동, 아주 오래된 크롬되어 있어야합니다 : jsfiddle.net/y0z9h9m7
이안

14

편집하다: "정답"으로 표시된 답변이 올바르지 않습니다.

쉬운 일입니다. 이 코드를 사용하여 "ie.jpg"를 원하는 사진으로 바꾸십시오.

<!DOCTYPE HTML>
<html>
    <head>
        <script>
            var canvas;
            var context;
            var ga = 0.0;
            var timerId = 0;

            function init()
            {
                canvas = document.getElementById("myCanvas");
                context = canvas.getContext("2d");
                timerId = setInterval("fadeIn()", 100);
            }

            function fadeIn()
            {
                context.clearRect(0,0, canvas.width,canvas.height);
                context.globalAlpha = ga;
                var ie = new Image();
                ie.onload = function()
                {
                    context.drawImage(ie, 0, 0, 100, 100);
                };
                ie.src = "ie.jpg";

                ga = ga + 0.1;
                if (ga > 1.0)
                {
                    goingUp = false;
                    clearInterval(timerId);
                }
            }
        </script>
    </head>
    <body onload="init()">
        <canvas height="200" width="300" id="myCanvas"></canvas>
    </body>
</html>

핵심은 globalAlpha 속성입니다.

Win7에서 IE 9, FF 5, Safari 5 및 Chrome 12로 테스트되었습니다.


13

게시물이 오래되었습니다. 내 제안과 함께 갈 것입니다. 제안은 캔버스 2D 컨텍스트에서 픽셀 조작을 기반으로합니다. MDN에서 :

바이트 수준에서 캔버스의 픽셀 데이터를 직접 조작 할 수 있습니다

픽셀을 조작하기 위해 여기서는 getImageData와 putImageData의 두 가지 함수를 사용합니다.

getImageData 함수 사용법 :

var myImageData = context.getImageData (왼쪽, 위, 너비, 높이);

putImageData 구문 :

context.putImageData (myImageData, dx, dy); // dx, dy-캔버스의 x 및 y 오프셋

어디 문맥은 당신의 캔버스 2D 컨텍스트입니다

빨간색 녹색 파란색과 알파 값을 얻으려면 다음을 수행하십시오.

var r = imageData.data[((x*(imageData.width*4)) + (y*4))];
var g = imageData.data[((x*(imageData.width*4)) + (y*4)) + 1];
var b = imageData.data[((x*(imageData.width*4)) + (y*4)) + 2];
var a = imageData.data[((x*(imageData.width*4)) + (y*4)) + 3];

여기서 x 는 x 오프셋이고 y 는 캔버스에서 y 오프셋입니다.

이미지를 반투명하게 만드는 코드가 있습니다.

var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var img = new Image();
img.onload  = function() {
   c.drawImage(img, 0, 0);
   var ImageData = c.getImageData(0,0,img.width,img.height);
   for(var i=0;i<img.height;i++)
      for(var j=0;j<img.width;j++)
         ImageData.data[((i*(img.width*4)) + (j*4) + 3)] = 127;//opacity = 0.5 [0-255]
   c.putImageData(ImageData,0,0);//put image data back
}
img.src = 'image.jpg';

"셰이더"를 직접 만들 수 있습니다. 여기에서 전체 MDN 기사를 참조 하십시오.


7

할 수 있습니다. 대상 아웃 글로벌 컴포지트 작업 을 사용하여 투명 캔버스를 빠르게 흐리게 처리 할 수 ​​있습니다 . 100 % 완벽하지는 않지만 때로는 흔적을 남기지 만 필요한 것에 따라 조정할 수 있습니다 (예 : 'source-over'를 사용하고 0.13에서 알파로 흰색으로 채우고 캔버스를 준비하기 위해 페이드하십시오).

// Fill canvas using 'destination-out' and alpha at 0.05
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.fillRect(0, 0, width, height);
ctx.fill();
// Set the default mode.
ctx.globalCompositeOperation = 'source-over';

3

나는 이것이 가장 좋은 질문에 대답한다고 생각합니다. 실제로 이미 그려진 것의 알파 값을 변경합니다. 이 질문을 받았을 때 이것은 아마도 API의 일부가 아니었을 것입니다.

주어진 2D 컨텍스트 c.

function reduceAlpha(x, y, w, h, dA) {
    var screenData = c.getImageData(x, y, w, h);
    for(let i = 3; i < screenData.data.length; i+=4){
    screenData.data[i] -= dA; //delta-Alpha
    }
    c.putImageData(screenData, x, y );
}

이 답변은 7 년 전에 자세히 설명 된 Soul_man의 답변과 어떻게 다릅니 까?
BReddy

-2

당신이 사용하는 경우 jCanvas의 라이브러리를 당신이 사용할 수있는 불투명도 그릴 때 속성을. 그 위에 페이드 효과가 필요한 경우 다른 값으로 다시 그립니다.


-11

당신은 할 수 없습니다. 즉시 모드 그래픽입니다. 그러나 불투명 한 배경색으로 사각형 위에 사각형을 그려서 시뮬레이션 할 수 있습니다.

이미지가 일정한 색 이외의 다른 위에 있으면 조금 까다로워집니다. 이 경우 픽셀 조작 방법을 사용할 수 있어야합니다. 이미지를 그리기 전에 영역을 저장 한 다음 나중에 불투명도와 혼합하십시오.


5
이 볼 정답 아닌 아래
라이언 Badour을

캔버스에 그린 요소 중 하나의 불투명도는 변경할 수 없지만 전체 캔버스의 불투명도는 변경할 수 있습니다. 경우에 따라 충분할 수도 있습니다.
MPG

2
MPG-귀하의 의견 (5 월 11 일)도 잘못되었습니다. 캔버스의 불투명도를 변경할 수 있지만 OP가 원하는 것이 아니며 위의 답변에서 제안되는 것이 아닙니다.
Ian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.