Chcę pobrać nieregularny kształt z istniejącego obrazu i renderować go jako nowy obraz w JavaScript przy użyciu kanonów HTML5. Zatem skopiowane zostaną tylko dane wewnątrz granicy wielokąta. Podejście, na które się natknąłem:Maska dla putImageData z kanwą HTML5?
- Narysuj wielokąt w nowym obszarze roboczym.
- utworzyć maskę korzystając
clip
- skopiować dane z oryginalnego płótna za pomocą
getImageData
(prostokąt) - Zastosuj dane do nowego płótnie przy użyciu
putImageData
to nie działa, cały prostokąt (np. rzeczy ze źródła poza granicą) wciąż się pojawia. This question wyjaśnia, dlaczego: "Specyfikacja mówi, że obszary przycinania nie będą miały wpływu na putImageData
". Dang!
Próbowałem także rysować kształt, ustawiając context.globalCompositeOperation = "source-in"
, a następnie używając putImageData
. Ten sam wynik: żadna maska nie została zastosowana. Podejrzewam z podobnego powodu.
Wszelkie sugestie, jak osiągnąć ten cel? Oto podstawowy kod mojej pracy w toku, na wypadek, gdyby nie było jasne, co próbuję zrobić. (Nie próbuj zbyt mocno, aby to debugować, jest czyszczone/wyodrębniane z kodu, który używa wielu funkcji, których nie ma tutaj, po prostu próbując pokazać logikę).
// coords is the polygon data for the area I want
context = $('canvas')[0].getContext("2d");
context.save();
context.beginPath();
context.moveTo(coords[0], coords[1]);
for (i = 2; i < coords.length; i += 2) {
context.lineTo(coords[i], coords[i + 1]);
}
//context.closePath();
context.clip();
$img = $('#main_image');
copy_canvas = new_canvas($img); // just creates a new canvas matching dimensions of image
copy_ctx = copy.getContext("2d");
tempImage = new Image();
tempImage.src = $img.attr("src");
copy_ctx.drawImage(tempImage,0,0,tempImage.width,tempImage.height);
// returns array x,y,x,y with t/l and b/r corners for a polygon
corners = get_corners(coords)
var data = copy_ctx.getImageData(corners[0],corners[1],corners[2],corners[3]);
//context.globalCompositeOperation = "source-in";
context.putImageData(data,0,0);
context.restore();
Niesamowite! To działa! Dzięki wielkie. –
Oh szybkie pytanie - czy możesz wymyślić sposób, aby to zrobić bez trzech tymczasowych. płótna? Mam 1, aby załadować kopię głównego obrazu, potem jeden, aby skopiować prostokąt na, a trzeci, który ma maskę, do której stosuję drugą. Czuję, że muszę gdzieś robić za dużo, ale nie mogę wymyślić sposobu, aby przejść bezpośrednio z pełnego obrazu do płótna zawierającego tylko prostokąt. –
W kodzie, który zawierałem, możesz zbudować kompozyt, który może utworzyć listę tylu obrazów, ile chcesz, jednak radzę ci to robić ostrożnie z punktu widzenia wydajności. Testowanie i wypróbowywanie to dobra praktyka;) –