imagenes data content javascript html5 canvas html5-canvas png

data - Método de Javascript para detectar el área de un PNG que no es transparente



javascript save canvas content (1)

Qué necesitas hacer:

  • Obtener el buffer
  • Obtenga una referencia de 32 bits de ese búfer (si sus otros píxeles son transparentes, puede usar un búfer Uint32Array para iterar).
  • Escanear 0 - ancho para encontrar el borde x1
  • Ancho de escaneo: 0 para encontrar el borde x2
  • Escanear 0 - altura para encontrar el borde y1
  • Altura de escaneo - 0 para encontrar el borde y2

Estos escaneos se pueden combinar, pero por simplicidad mostraré cada paso por separado.

Demostración en línea de esto se puede encontrar aquí.

Resultado:

Cuando se carga la imagen, inclúyala (si la imagen es pequeña, el resto de este ejemplo sería un desperdicio, ya que sabría las coordenadas al dibujarlo, asumiendo que la imagen que dibuje es grande con una pequeña imagen dentro)

(nota: esta es una versión no optimizada por simplicidad)

ctx.drawImage(this, 0, 0, w, h); var idata = ctx.getImageData(0, 0, w, h), // get image data for canvas buffer = idata.data, // get buffer (unnes. step) buffer32 = new Uint32Array(buffer.buffer), // get a 32-bit representation x, y, // iterators x1 = w, y1 = h, x2 = 0, y2 = 0; // min/max values

Luego escanea cada borde. Para el borde izquierdo, escanea de 0 a ancho para cada línea (no optimizada):

// get left edge for(y = 0; y < h; y++) { // line by line for(x = 0; x < w; x++) { // 0 to width if (buffer32[x + y * w] > 0) { // non-transparent pixel? if (x < x1) x1 = x; // if less than current min update } } }

Para el borde derecho solo invierte x iterador:

// get right edge for(y = 0; y < h; y++) { // line by line for(x = w; x >= 0; x--) { // from width to 0 if (buffer32[x + y * w] > 0) { if (x > x2) x2 = x; } } }

Y lo mismo es para los bordes superiores e inferiores solo que los iteradores están invertidos:

// get top edge for(x = 0; x < w; x++) { for(y = 0; y < h; y++) { if (buffer32[x + y * w] > 0) { if (y < y1) y1 = y; } } } // get bottom edge for(x = 0; x < w; x++) { for(y = h; y >= 0; y--) { if (buffer32[x + y * w] > 0) { if (y > y2) y2 = y; } } }

La región resultante es entonces:

ctx.strokeRect(x1, y1, x2-x1, y2-y1);

Hay varias optimizaciones que podría implementar pero dependen completamente del escenario, como si conoce la ubicación aproximada, entonces no tiene que iterar todas las líneas / columnas.

Podría hacer una estimación de la fuerza bruta de la ubicación omitiendo x número de píxeles y cuando encuentre un píxel no transparente podría hacer un área de búsqueda máxima en función de eso, etc., pero eso está fuera del alcance aquí.

¡Espero que esto ayude!

Estoy buscando un método de JavaScript para detectar una imagen dentro de un archivo PNG transparente. Por ejemplo, crearé un PNG con un lienzo transparente de 940x680, luego colocaré un objeto de opacidad completo en algún lugar dentro de ese lienzo.

Quiero ser capaz de detectar el tamaño (h / w) y la ubicación superior izquierda de ese objeto que no es transparente dentro del lienzo

Aquí hay un ejemplo de la imagen original Aquí hay un ejemplo de lo que me gustaría lograr. (Superposición de cuadro delimitador, con datos superiores + margen izquierdo)

He encontrado un recurso que detecta un poco la transparencia, pero no estoy seguro de cómo escalar algo así a lo que estoy buscando.

var imgData, width = 200, height = 200; $(''#mask'').bind(''mousemove'', function(ev){ if(!imgData){ initCanvas(); } var imgPos = $(this).offset(), mousePos = {x : ev.pageX - imgPos.left, y : ev.pageY - imgPos.top}, pixelPos = 4*(mousePos.x + height*mousePos.y), alpha = imgData.data[pixelPos+3]; $(''#opacity'').text(''Opacity = '' + ((100*alpha/255) << 0) + ''%''); }); function initCanvas(){ var canvas = $(''<canvas width="''+width+''" height="''+height+''" />'')[0], ctx = canvas.getContext(''2d''); ctx.drawImage($(''#mask'')[0], 0, 0); imgData = ctx.getImageData(0, 0, width, height); }

Violín