Maskowanie / nakładanie obrazu na płótnie

W moim projekcie muszę zaimplementować jeden inny obraz kolorowy na innym obrazie o tym samym rozmiarze i wzorze za pomocą płótna, a obrazy nie są w kształcie okrągłym lub prostokątnym. Wszystkie są w kształcie fal i będą stosowane na jednym głównym obrazie tła do wyświetlania wielu grafik na każdej funkcji onclick.

Nakładający się obraz powinien zostać zmieniony na inny wybrany kolor. Moje pytanie jest w jakiś sposób z użyciem canvas z tego możemy zmienić kolor obrazu, który jest rysowany przez canvas lub my trzeba zawsze używać różnych obrazów i stosować z CSS / jQuery.

Czytałem o maskowaniu i nakładaniu obrazów na płótno. Ale nie mogę zrozumieć z moich obrazów, ponieważ nie są w kształcie kwadratu lub koła, a następnie pierwszą rzeczą jest, jak rysuję wiele kształtów fal na jednym obrazie. Nie mam pojęcia, że szukałem, ale nie znalazłem idealnego rozwiązania.

Moje potrzeby to po prostu narysować jeden obraz fali na płótnie i zmienić jego kolor z funkcji kliknięcia, a także ustawić inny div z tło-obraz, a także więcej niż dwa płótna będą nakładać się na siebie. Czy to możliwe?

(to znaczy: ta funkcja służy do tworzenia lub ustawiania wielu grafik na samochodzie, aby każdy obraz graficzny musiał być ustawiony na płótnie, a inna grafika musi nakładać się na div I pierwsze płótno)

Author: Community, 2013-08-22

2 answers

Do zastąpienia części obrazu można użyć komponowania kontekstowego.

Na przykład, jeśli masz już to niebieskie logo jako obrazek:

Tutaj wpisz opis obrazka

Jeśli chcesz, aby górna część logo miała kolor fioletowy:

Tutaj wpisz opis obrazka

Możesz użyć komponowania, aby zmienić kolor górnej części obrazu.

Najpierw użyj ulubionego edytora obrazów, aby przyciąć dowolną część, której nie chcesz ponownie pokolorować.

To, co pozostało, nazywa się nakładka.

Ta nakładkowa część obrazu jest tym, co programowo przebarwimy.

Tutaj wpisz opis obrazka

Ta nakładka może być programowo przebarwiona na dowolny kolor.

Tutaj wpisz opis obrazkaTutaj wpisz opis obrazka

Jak nakładka została programowo przebarwiona:

  1. narysuj nakładkę na pustym płótnie.
  2. Ustaw tryb komponowania na "source-in".
  3. efekt: tylko istniejące piksele są zastępowane-przezroczyste piksele pozostają transparent
  4. teraz narysuj prostokąt dowolnego koloru pokrywający płótno
  5. (pamiętaj, tylko istniejąca nakładka zostanie zastąpiona nowym kolorem)

Jak uzupełnić logo zmienionym kolorem nakładki

  1. Ustaw tryb kompozycji na "cel-szczyt"
  2. efekt: tylko przezroczyste piksele są zastępowane-istniejące piksele pozostają niezmienione
  3. Teraz narysuj oryginalne logo]}
  4. (remember, the istniejące kolorowe nakładki nie zostaną zastąpione)

Ten "cel-szczyt" efekt kompozycyjny jest czasami nazywany "rysowaniem pod".

Tę nakładkę można nawet zastąpić teksturami!

Tutaj wpisz opis obrazka

Oto kod i skrzypce: http://jsfiddle.net/m1erickson/bfUPr/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var truck,logo,overlay;
    var newColor="red";

    var imageURLs=[];
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/boxTruck.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmall.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmallOverlay.png");
    loadAllImages();

    function loadAllImages(){
        for (var i = 0; i < imageURLs.length; i++) {
          var img = new Image();
          imgs.push(img);
          img.onload = function(){ imagesOK++; imagesAllLoaded(); };
          img.src = imageURLs[i];
        }      
    }

    var imagesAllLoaded = function() {
      if (imagesOK==imageURLs.length ) {
         // all images are fully loaded an ready to use
         truck=imgs[0];
         logo=imgs[1];
         overlay=imgs[2];
         start();
      }
    };


    function start(){

        // save the context state
        ctx.save();

        // draw the overlay
        ctx.drawImage(overlay,150,35);

        // change composite mode to source-in
        // any new drawing will only overwrite existing pixels
        ctx.globalCompositeOperation="source-in";

        // draw a purple rectangle the size of the canvas
        // Only the overlay will become purple
        ctx.fillStyle=newColor;
        ctx.fillRect(0,0,canvas.width,canvas.height);

        // change the composite mode to destination-atop
        // any new drawing will not overwrite any existing pixels
        ctx.globalCompositeOperation="destination-atop";

        // draw the full logo
        // This will NOT overwrite any existing purple overlay pixels
        ctx.drawImage(logo,150,35);

        // draw the truck
        // This will NOT replace any existing pixels
        // The purple overlay will not be overwritten
        // The blue logo will not be overwritten
        ctx.drawImage(truck,0,0);

        // restore the context to it's original state
        ctx.restore();

    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=500 height=253></canvas>
</body>
</html>
 41
Author: markE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 17:54:04

Pytanie w obecnej formie jest IMO nieco niejasne. Aby dać bardziej ogólną odpowiedź, którą możesz zastosować do scenariusza, w którym potrzebujesz obcinania, możesz użyć (co najmniej) dwóch podejść:

Metoda 1 - użycie trybu kompozytowego do klipu

Tryb kompozytowy jest najprostszym sposobem, ale również najmniej elastycznym, ponieważ musisz wstępnie zdefiniować maskę przycinającą jako obraz z przezroczystym tłem (Zwykle PNG).

Możesz użyć stałych części obrazu, aby przyciąć następną narysowaną rzecz, lub użyj przezroczystych obszarów do wypełnienia.

Oto podejście, w którym używamy części stałych do przycinania następnego narysowanego kształtu / obrazu:

/// draw the shape we want to use for clipping
ctx1.drawImage(imgClip, 0, 0);

/// change composite mode to use that shape
ctx1.globalCompositeOperation = 'source-in';

/// draw the image to be clipped
ctx1.drawImage(img, 0, 0);

Tutaj globalCompositeOperation zmienia się na source-in, co oznacza, że obraz źródłowy (ten, który będziemy rysować obok miejsca docelowego) zostanie narysowany wewnątrz istniejących stałych danych. Nic nie zostanie przyciągnięte do przezroczystych obszarów.

Jeśli nasza maska obcinająca wygląda tak (losowe fair-use z sieci):

Maska Clip

I nasz obraz tak:

Główny obraz

Wynik będzie następujący:

Kompozycja obrazu

Metoda 2-Użycie ścieżki do klipu

Można również zdefiniować ścieżkę do przycinania. Jest to bardzo elastyczne, ponieważ możesz dostosować ścieżkę lub animować ją, jeśli chcesz.

Uwaga: Należy pamiętać, że przycinanie przy użyciu ścieżki jest obecnie nieco "kruche" w przeglądarkach, więc należy rozważyć użycie save() i restore() przed i po ustawieniu i użyciu ścieżki klipu, ponieważ przeglądarki nie są w stanie tego zrobić zresetuj klip w tej chwili (restore przywróci domyślny klip = pełne płótno);

Zdefiniujmy prostą ścieżkę zygzakowatą (w Twoim przypadku będą to twoje fale):

/// use save when using clip Path
ctx2.save();

ctx2.beginPath();
ctx2.moveTo(0, 20);
ctx2.lineTo(50,0);
/// ... more here - see demo
ctx2.lineTo(400, 20);
ctx2.lineTo(400, 100);
ctx2.lineTo(0, 100);
ctx2.closePath();

/// define this Path as clipping mask
ctx2.clip();

/// draw the image
ctx2.drawImage(img, 0, 0);

/// reset clip to default
ctx2.restore();

Teraz, gdy ustawiliśmy maskę przycinającą za pomocą clip wszystko, co zostanie narysowane na płótnie, zostanie przycięte, aby zmieścić się w tym kształcie (pamiętaj, że upewniamy się, że kształt może zakończyć się tam, gdzie się rozpoczął):

Ścieżka przycięty obraz

Zobacz demo online tych metod tutaj

 47
Author: epistemex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 17:35:39