2014-07-14 19 views
8

olarak birleştirin.Kanvas1'in rasgele bir görüntü (jpg, png veya benzeri) içerdiği ve kanvas2'nin siyah ve siyah olmayan pikseller içerdiği iki kanvasın gösterildiği gibi, kanvas görüntü ve tuval alfa maskesini, aynı piksel boyutuna sahip pn

i başarmak istediğinizi i canvas1 klonlamak ve (karanlığın bir eşik dahil olabilir) her siyah canvas2 pikseli bulunan canvas3 şeffaf olmasını istediğiniz üçüncü canvas3 kullanılarak

ben zaten böyle bir çalışma çözümüne sahip

:

canvas3context.drawImage(canvas1,0,0); 
var c3img = canvas3context.getImageData(0,0,canvas3.width,canvas3.height); 
var c2img = canvas2context.getImageData(0,0,canvas2.width,canvas2.height); 
loop(){ 
    if(c2img i-th,i+1-th,i+2-th pixel is lower than threshold) 
     set c3img.data[i]=c3img.data[i+1]=c3img.data[i+2]=c3img.data[i+3]=0 
} 

yukarıdaki (sözde) koduyla sorun yavaş yani, yüzden sorum şu: herkes nasıl bu ölçüde hızlandırmak için bir fikir paylaşabilirim? webgl hakkında düşündüm ama hiç bu işe yaramadı - bu yüzden shader'lar ya da bunun için gerekli olan araçlar ya da terimler hakkında hiçbir fikrim yok. başka bir fikir belki hiç canvas2 dönüştürmek (sadece yukarıdaki gibi bir döngü içinde her pikseli modifieng değil) bir şekilde çok hızlı beyaz & siyah herhangi bir yardım son derece takdir edilir

şeffaf pikseller oluşturmak için karışım modlarıyla işe yarayabilir olmasıydı

+0

Pikselleri yinelemekle ilgili bir başka sorun da, kanvas görüntü verilerinin okunmasının çapraz kaynaklı soruna geçebilmesidir. –

cevap

7

kendi sorumu yanıtlarken, siyah bir & beyaz görüntü ile rastgele bir görüntünün birleştirilmesi için bir çözüm sunarım. Hala eksik olan, bir kanvasın sadece bir rengi için alfa kanalını nasıl ayarlayacağınızdır.

Soruyu parçalardan ayırıp her birine cevap veriyorum.

Soru 1: Ya her piksel iterating olmadan gri ölçek bir tuval dönüştürmek için?

Cevap: karışım modu 'parlaklık'

function convertCanvasToGrayscale(canvas){ 
    var tmp = document.createElement('canvas'); 
    tmp.width = canvas.width; 
    tmp.height = canvas.height; 
    var tmpctx = tmp.getContext('2d'); 

    // conversion 
    tmpctx.globalCompositeOperation="source-over"; // default composite value 
    tmpctx.fillStyle="#FFFFFF"; 
    tmpctx.fillRect(0,0,canvas.width,canvas.height); 
    tmpctx.globalCompositeOperation="luminosity"; 
    tmpctx.drawImage(canvas,0,0); 

    // write converted back to canvas 
    ctx = canvas.getContext('2d'); 
    ctx.globalCompositeOperation="source-over"; 
    ctx.drawImage(tmp, 0, 0); 
} 

Soru 2 olan beyaz tuval üzerine resim çizmek: yineleme olmadan & siyah beyaz bir gri tonlama tuval dönüştürmek için nasıl her piksel?

Cevap: Renk #FEFEFE ile iki kez renk yakar karıştırma modu işini

function convertGrayscaleCanvasToBlackNWhite(canvas){ 
    var ctx = canvas.getContext('2d'); 

    // in case the grayscale conversion is to bulky for ya 
    // darken the canvas bevore further black'nwhite conversion 
    //for(var i=0;i<3;i++){ 
    // ctx.globalCompositeOperation = 'multiply'; 
    // ctx.drawImage(canvas, 0, 0); 
    //} 

    ctx.globalCompositeOperation = 'color-dodge'; 
    ctx.fillStyle = "rgba(253, 253, 253, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
    ctx.globalCompositeOperation = 'color-dodge'; 
    ctx.fillStyle = "rgba(253, 253, 253, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
} 

Not yapacağız: Bu işlev, siyah alanlar siyah ve olmayan her siyah piksel sola istediğinizi varsayar beyaz ol! bu nedenle siyah piksel içermeyen gri tonlamalı bir resim tamamen beyaz olacak bu işlemi seçmemin sebebi benim durumumda daha iyi çalıştığı ve sadece iki harmanlama işleminin kullanılması, onun oldukça hızlı olması demektir - daha fazla karanlık pikselin siyah kalmasını istiyorsanız ve Daha fazla beyaz piksel beyaz olur, daha önce görüntüyü karartmak için yorumlanmış döngüyü kullanabilirsiniz. Böylece karanlık piksel siyah olur ve daha parlak piksel daha koyu olur. Tekrar iş

Soru 3 kalanını yapacak siyah pikselin kullanarak renk atlatmak miktarını artırmak olarak: nasıl iterating olmadan başka tuval her piksel ile Siyah & Beyaz tuval birleştirmek?

Cevap: kullanımı 'çarpın' karıştırma modu

function getBlendedImageWithBlackNWhite(canvasimage, canvasbw){ 
    var tmp = document.createElement('canvas'); 
    tmp.width = canvasimage.width; 
    tmp.height = canvasimage.height; 

    var tmpctx = tmp.getContext('2d'); 

    tmpctx.globalCompositeOperation = 'source-over'; 
    tmpctx.drawImage(canvasimage, 0, 0); 

    // multiply means, that every white pixel gets replaced by canvasimage pixel 
    // and every black pixel will be left black 
    tmpctx.globalCompositeOperation = 'multiply'; 
    tmpctx.drawImage(canvasbw, 0, 0); 

    return tmp; 
} 

Soru 4: iterating olmadan her pikseli bir Siyah & Beyaz tuval ters çevirmek için nasıl?

Yanıt: Bir performansı ile ilgili

convertCanvasToGrayscale(canvasmask); 
convertGrayscaleCanvasToBlackNWhite(canvasmask); 
result = getBlendedImageWithBlackNWhite(canvasimage, canvasmask); 

yapabilir kullanım 'fark', karışım kipi 'birleştirme' bir canvasmask bir canvasimage Şimdi

function invertCanvas(canvas){ 
    var ctx = canvas.getContext("2d"); 

    ctx.globalCompositeOperation = 'difference'; 
    ctx.fillStyle = "rgba(255, 255, 255, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
} 

: Açıkçası bu karışım modları her pikselin modifenginden çok daha hızlıdır ve biraz daha hızlı bir şekilde tüm fonksiyonları tek bir işlevde toplayabilir ve yalnızca bir tmpcanvası geri dönüştürebilir - ama r eader ^^ Bir sidenote olarak

: Yukarıdaki aynı görüntü ile getBlendedImageWithBlackNWhite bir sonuç karşılaştırmak ama siyah alanlar alfa kanalı her pikseli yineleme ve ayarlayarak saydam yapıldığında ı test çıkan png boyutunu nasıl farklı farkı boyutu hemen hemen hiçbir şey değildir ve bu nedenle her siyah pikselin şeffaf olması gerektiği anlamına gelen alfa maskesine ihtiyacınız yoksa, daha fazla işleme için yeterli olabilir

not: Biri siyah beyazın anlamını tersine çevirebilir. invertCanvas() işlevi, bu karışım modlarını neden kullandığımı veya nasıl harmanlandığımı daha fazla bilmek isterseniz,

des gerçekten arkalarındaki matematik kontrol etmelidir çalışmak - Ya onlar gerçekten nasıl çalıştığını bilmiyorum eğer imho böyle fonksiyonlarını geliştirmek mümkün değil: math behind blend modes canvas composition standard including a bit math

bir örnek gerekirse - fark yer: http://jsfiddle.net/C3fp4/1/

+0

Harika şeyler. Bu globalCompositeOperation filtrelerinden bazılarının henüz safari'de çalışmadığını unutmayın. – Mulhoon