Necesito atravesar una imagen .gif y determinar el valor RGB de cada píxel, coordenadas xey. ¿Puede alguien darme una visión general de cómo puedo lograr esto? (metodología, qué espacios de nombres usar, etc.)¿Cómo puedo iterar a través de cada píxel en una imagen .gif?
Respuesta
Este es un ejemplo completo con ambos métodos, utilizando LockBits() y GetPixel(). Además de los problemas de confianza con LockBits() las cosas pueden ponerse peludas fácilmente.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace BitmapReader
{
class Program
{
static void Main(string[] args)
{
//Try a small pic to be able to compare output,
//a big one to compare performance
System.Drawing.Bitmap b = new
System.Drawing.Bitmap(@"C:\Users\vinko\Pictures\Dibujo2.jpg");
doSomethingWithBitmapSlow(b);
doSomethingWithBitmapFast(b);
}
public static void doSomethingWithBitmapSlow(System.Drawing.Bitmap bmp)
{
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
Color clr = bmp.GetPixel(x, y);
int red = clr.R;
int green = clr.G;
int blue = clr.B;
Console.WriteLine("Slow: " + red + " "
+ green + " " + blue);
}
}
}
public static void doSomethingWithBitmapFast(System.Drawing.Bitmap bmp)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect,
System.Drawing.Imaging.ImageLockMode.ReadOnly,
bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr,
rgbValues, 0, bytes);
byte red = 0;
byte green = 0;
byte blue = 0;
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
//See the link above for an explanation
//of this calculation
int position = (y * bmpData.Stride) + (x * Image.GetPixelFormatSize(bmpData.PixelFormat)/8);
blue = rgbValues[position];
green = rgbValues[position + 1];
red = rgbValues[position + 2];
Console.WriteLine("Fast: " + red + " "
+ green + " " + blue);
}
}
bmp.UnlockBits(bmpData);
}
}
}
Puede cargar la imagen utilizando new Bitmap(filename)
y luego usar Bitmap.GetPixel
repetidamente. Esto es muy lento pero simple. (Consulte la respuesta de Vinko para ver un ejemplo.)
Si el rendimiento es importante, es posible que desee utilizar Bitmap.LockBits
y el código inseguro. Obviamente, esto reduce el número de lugares en los que podría usar la solución (en términos de niveles de confianza) y generalmente es más complejo, pero puede ser lote más rápido.
Wow. Estaba buscando esto hace unas semanas. Definitivamente mirará más en el ejemplo. Gracias por el enlace. – maxwellb
Es mucho más complejo (y bastante más rápido), debe tener en cuenta el PixelFormat de la imagen, comprobar si los datos están o no rellenos y omitir algunos valores en consecuencia. El ejemplo de MSDN no es particularmente útil ya que no menciona nada de esto. –
- 1. Perl iterar a través de cada coincidencia
- 2. ¿Cómo puedo iterar a través de una cadena en Python?
- 3. ¿Cómo puedo iterar a través de cada elemento en una matriz n-dimensional en MATLAB?
- 4. Iterar a través de cada dígito en un número
- 5. Cómo iterar a través de una cadena
- 6. Cómo iterar a través de una DataTable
- 7. Iterar a través de cada archivo en un directorio
- 8. Leer una imagen píxel por píxel en Ruby
- 9. ¿Cómo puedo iterar a través de elementos DOM en PHP?
- 10. ¿Cómo manipular una imagen a nivel de píxel en C?
- 11. Iterar a través de cada "coincidencia" (Ruby regex)
- 12. ¿Cómo puedo iterar a través de elementos de QListWidget y trabajar con cada elemento?
- 13. Iterar a través de DataSet
- 14. Iterar a través de una matriz C
- 15. C# ¿Cómo puedo iterar a través del registro?
- 16. Java ¿Loop a través de los píxeles en una imagen?
- 17. Cómo iterar a través de los elementos de una vista
- 18. ¿Cómo puedo generar imágenes GIF en .NET?
- 19. ¿Cómo iterar a través de una cadena y verificar el valor de bytes de cada carácter?
- 20. ¿Cómo puedo editar una imagen jpg a través de Java?
- 21. Cómo iterar a través de un fd_set
- 22. Cómo iterar a través de SAFEARRAY **
- 23. Java convertir imagen GIF a formato PNG
- 24. Iterar a través de una matriz de cadenas en Java
- 25. ¿Cómo iterar a través de cada propiedad de un objeto vb.net personalizado?
- 26. ¿Cómo puedo superponer una imagen a otra?
- 27. Obtención de valores RGB para cada píxel desde una imagen sin procesar en C
- 28. ¿Cómo iterar a través de cada archivo/directorio recursivamente en C++ estándar?
- 29. Iterar a través de elementos en una enumeración en Delphi
- 30. Iterar a través fechas en SQL
Nunca he podido implementar ningún tipo de procesamiento de imágenes usando Get/SetPixel. Siempre * es * demasiado lento, incluso para operaciones triviales como el aumento del brillo general. –
Siempre es demasiado lento cuando las imágenes son grandes. Para imágenes de tamaño de icono, es perfectamente adecuado :-) –
Oh, bueno, sí :-) –