2008-12-24 8 views
3

J'ai un tableau de int pixels dans mon programme C# et je veux le convertir en image. Le problème est que je convertis le code source Java d'un programme en code C# équivalent. Dans java la ligne lit qui affiche le tableau de pixels int dans l'image:Conversion d'une matrice de pixels en une image en C#

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

quelqu'un peut me dire le C# équivalent?

Ici orig est le tableau de int pixels. J'ai cherché la classe Bitmap et il y a une méthode appelée SetPixel mais le problème est qu'il faut un nombre de coordonnées x, y. Mais ce que j'ai dans mon code est un tableau de int pixels. Une autre chose étrange est mon tableau orig a un nombre négatif et ils sont loin de 255. En Java c'est le même cas (ce qui signifie que le tableau en C# et Java ont une valeur équivalente) et les valeurs fonctionnent bien en Java. Mais je ne peux pas obtenir cette ligne traduite en C#

S'il vous plaît aider.

+0

Les valeurs négatives sont probablement parce que les valeurs int sont censés être non signés. Cela ne dérange pas s'ils sont signés, mais non signés aurait plus de sens. –

Répondre

2

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

+0

+1. Si vous devez traiter toute l'image, alors SetPixel/GetPixel sont SLOW. –

1

Eh bien, je suppose que chaque int est la valeur ARGB composite? S'il n'y a pas une option facile, alors LockBits pourrait être utile de regarder - ce sera beaucoup plus rapide que SetPixel, mais est plus complexe. Vous devrez également vous assurer de savoir comment l'int est composé (ARGB? RGBA?). Je vais essayer de voir s'il y a une option plus évidente ...

6

En utilisant WPF, vous pouvez créer un bitmap (image) directement à partir de votre tableau. Vous pouvez ensuite encoder cette image ou de l'afficher ou jouer avec:

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); 
+0

Je cherchais cela et j'étais gaffeur avec la valeur rawstride. Vous code travaillé comme un charme pour moi .. Merci ... +1 :) –

+1

D'où viennent les 7 et 8 dans '(largeur * pf.BitsPerPixel + 7)/8'? –

0

Je recommanderais d'utiliser LockBits mais un algorithme basé SetPixel plus lent 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; 
} 
0

MemoryImageSource 3ème argument de l » constructeur est un tableau d'entiers composés de valeurs argb dans cet ordre

L'exemple de cette page crée un tel tableau par;

pix[index++] = (255 << 24) | (red << 16) | blue; 

Vous devez décomposer ce tableau entier à un tableau d'octets (opérateur de décalage serait utile), mais il devrait être pour BGR, pour la méthode LockBits pour travailler.

+0

Votre lien semble être mort. – starbeamrainbowlabs

2

J'aime l'option WPF déjà présenté, mais ici il utilise LockBits et 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 (sous forme de 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; 
    } 
Questions connexes