2010-12-03 32 views
8

Estoy tratando de abrir un archivo de imagen y almacenar una lista de píxeles por color en una variable/matriz para que pueda mostrarlos uno por uno.Leer una imagen píxel por píxel en Ruby

Tipo de imagen: podría ser BMP, JPG, GIF o PNG. Cualquiera de ellos está bien y solo uno necesita ser apoyado. Salida de color: RGB o Hex.

He visto un par de bibliotecas (RMagick, Quick_Magick, Mini_Magick, etc.) y todas parecen exageradas. Heroku también tiene algún tipo de dificultad con ImageMagick y mis pruebas no se ejecutan. Mi aplicación está en Sinatra.

¿Alguna sugerencia?

Respuesta

13

Puede usar el método Rmagickeach_pixel para esto. each_pixel recibe un bloque. Para cada píxel, el bloque pasa el píxel, el número de columna y el número de fila del píxel. Se repite sobre los píxeles de izquierda a derecha y de arriba a abajo.

Así que algo como:

pixels = [] 

img.each_pixel do |pixel, c, r| 
    pixels.push(pixel) 
end 
# pixels now contains each individual pixel of img 
+0

Simplemente curioso; ¿Cómo es el rendimiento de Rmagick en este caso? Trabajo en un motor de juego como un pasatiempo que utiliza una interfaz de usuario de color rubí y su clase de mapa de bits incorporado es extremadamente lenta en lo que respecta al acceso de píxel por píxel. –

+0

La pregunta original indica que el autor ha mirado a RMagick y ha determinado que es "exagerado". – Phrogz

+2

@Phogz ¿Así que bajas? Aunque el OP determina que es excesivo, no significa que lo sea. Si * realmente supieran * lo que necesitaban, no lo habrían preguntado. Esta respuesta es correcta y hace lo que se pide. – Alex

1

Si sólo está abriendo el archivo para mostrar los bytes, y no es necesario manipularlo como una imagen, entonces se trata de un simple proceso de abrir el archivo como cualquier otro, leyendo X cantidad de bytes, luego iterando sobre ellos. Algo como:

File.open('path/to/image.file', 'rb') do |fi| 
    byte_block = fi.read(1024) 
    byte_block.each_byte do |b| 
    puts b.asc 
    end 
end 

Eso meramente dará como resultado bytes como decimal. Querrá ver los valores de byte y crear valores RGB para determinar los colores, por lo que quizás usar each_slice(3) y leer en múltiplos de 3 bytes ayude.

Varios formatos de imagen contienen diferentes encabezados y bloques de seguimiento utilizados para almacenar información sobre la imagen, formato de datos e información EXIF ​​para el dispositivo de captura, dependiendo del tipo. Probablemente ir con algo que no esté comprimido sería bueno si vas a leer un archivo y enviar los bytes directamente, como TIFF sin comprimir. Una vez que haya decidido que puede saltar al archivo para saltear encabezados si lo desea, o simplemente leer los también para ver o aprender lo que hay en ellos. La página de Wikipedia Image file formats es un buen lugar para más información sobre los diversos formatos disponibles.

Si solo quiere ver los datos de la imagen, una de las bibliotecas de alto nivel lo ayudará ya que tienen interfaces para captar determinadas secciones de la imagen. Pero, en realidad, acceder a los bytes no es difícil, ni es para saltar.

Si desea obtener más información sobre el bloque EXIF, se utiliza para describir muchos formatos Jpeg y TIFF de diferentes proveedores ExifTool puede ser útil. Está escrito en Perl para que pueda ver cómo funciona el código. Los documentos muestran muy bien los bloques y campos del encabezado, y usted puede leer/escribir valores usando la aplicación.

Estoy en el proceso de probar un nuevo enrutador, así que no he tenido la oportunidad de probar ese código, pero debe estar cerca. Lo verificaré un poco y actualizaré la respuesta si eso no funcionó.

+2

Usted sabe que el formato de archivo va a importar aquí, ¿verdad? –

+0

Debo aclarar; El formato importa porque el OP no quiere información del encabezado ni otras cosas, solo datos de píxeles. –

+0

OP no especifica que los encabezados se salten. Si está asumiendo quizás pueda pedirle al OP que aclare en lugar de rechazarlo. –

14

Creo que Chunky PNG debería hacerlo por usted. Es rubí puro, razonablemente liviano, eficiente en la memoria y proporciona acceso a datos de píxeles, así como a metadatos de imágenes.

+0

+1, buena biblioteca. Esta respuesta sería aún mejor si proporcionó un fragmento de código que utiliza 'Chunky PNG' para hacer lo que se le pide. Pero, * esta biblioteca es solo para PNG. * El OP especifica que el archivo podría ser más que PNG. – Alex

+4

@Alex Creo que ha leído mal el PO. Dice que "cualquiera de ellos está bien y solo uno necesita apoyo". Lo interpreto en el sentido de que el OP usará cualquier formato que sea más fácil basado en la biblioteca. – Phrogz

+0

Correcto, solo admite PNG está bien. Menciona que no necesita RMagick obviamente, pero ¿todavía requiere soporte de ImageMagick? –

Cuestiones relacionadas