3 votes

Conversion d'un tableau de pixels en une image en C#

J'ai un tableau de int pixels dans mon programme C# et je veux le convertir en une image. Le problème est que je convertis le code source Java d'un programme en code C# équivalent. En Java, la ligne se lit comme suit : "affiche le tableau de pixels int dans une image" :

Image output = createImage(new MemoryImageSource(width, height, orig, 0, width));

Quelqu'un peut-il me dire quel est l'équivalent en C# ?

Ici, orig est le tableau de int pixels. J'ai cherché dans la classe Bitmap et il y a une méthode appelée SetPixel mais le problème est qu'il faut un numéro de coordonnées x,y. Mais ce que j'ai dans mon code est un tableau de int pixels. Une autre chose étrange est que mon tableau d'origine a des nombres négatifs et qu'ils sont très éloignés de 255. En Java, c'est le même cas (ce qui signifie que les tableaux en C# et en Java ont des valeurs équivalentes) et les valeurs fonctionnent bien en Java.

Mais je n'arrive pas à traduire cette ligne en C#. Merci de m'aider.

6voto

Frank Krueger Points 27508

Avec WPF, vous pouvez créer une image bitmap directement à partir de votre tableau. Vous pouvez ensuite encoder cette image, l'afficher ou jouer avec elle :

int width = 200;
int height = 200;

//
// Here is the pixel format of your data, set it to the proper value for your data
//
PixelFormat pf = PixelFormats.Bgr32;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;

//
// Here is your raw data
//
int[] rawImage = new int[rawStride * height / 4];

//
// Create the BitmapSource
//
BitmapSource bitmap = BitmapSource.Create(
    width, height,
    96, 96, pf, null,
    rawImage, rawStride);

2voto

mackenir Points 4271

Vous pouvez utiliser Bitmap.LockBits pour obtenir les données bitmap que vous pouvez ensuite manipuler directement, plutôt que via SetPixel. ( Comment utiliser LockBits )

2voto

Marc Gravell Points 482669

J'aime bien l'option WPF déjà présentée, mais la voici en utilisant LockBits y Bitmap :

        // get the raw image data
        int width, height;
        int[] data = GetData(out width, out height);

        // create a bitmap and manipulate it
        Bitmap bmp = new Bitmap(width,height, PixelFormat.Format32bppArgb);
        BitmapData bits = bmp.LockBits(new Rectangle(0, 0, width, height),
            ImageLockMode.ReadWrite, bmp.PixelFormat);
        unsafe
        {
            for (int y = 0; y < height; y++)
            {
                int* row = (int*)((byte*)bits.Scan0 + (y * bits.Stride));
                for (int x = 0; x < width; x++)
                {
                    row[x] = data[y * width + x];
                }
            }
        }
        bmp.UnlockBits(bits);

Avec (comme données de test) :

    public static int[] GetData(out int width, out int height)
    {
        // diagonal gradient over a rectangle
        width = 127;
        height = 128;
        int[] data =  new int[width * height];
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                int val = x + y;
                data[y * width + x] = 0xFF << 24 | (val << 16) | (val << 8) | val;
            }
        }
        return data;
    }

1voto

Marc Gravell Points 482669

Je suppose que chaque valeur int est la valeur ARGB composite ? S'il n'y a pas d'option facile, alors LockBits pourrait valoir la peine d'être examinée - elle sera beaucoup plus rapide que la SetPixel mais elle est plus complexe. Vous devrez également vous assurer que vous savez comment l'int est composé (ARGB ? RGBA ?). Je vais essayer de voir s'il n'y a pas une option plus évidente...

0voto

user21826 Points 1048

Je recommanderais d'utiliser LockBits, mais un algorithme plus lent basé sur SetPixel pourrait ressembler à quelque chose comme

// width - how many int's per row        
// array - array of integers
Bitmap createImage(int width, int[] array)
{            
  int height = array.Length / width;
  Bitmap bmp = new Bitmap(width, height);
  for (int y = 0; y < height; y++)
  {
    for (int x = 0; x < array.Length; x += width)
    {
      bmp.SetPixel(x, y, Color.FromArgb(array[i]));
    }
  }
  return bmp;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X