2010-12-10 8 views
1

Ich versuche ein Bild zu manipulieren, ich bin ziemlich neu, wenn es um Bitmaps geht und Bilder so leer mit meinem auf meine Frage und Code. Ich initialisiere ein Byte-Array, um Bgr24 Pixeldaten zu speichern, damit ich es in ein BitmapSource-Objekt übergeben kann. Aber mein Pixel-Array hat nicht die richtige Größe "Ich denke".Probleme mit BitmapSource-Objekt in C#

Die letzte Zeile des Codes ist eigentlich, wo mein Problem ist, der Parameter "Pixel" wirft mir den folgenden Fehler "System.ArgumentException wurde nicht behandelt Wert nicht in den erwarteten Bereich fallen."

ich initialisieren diese Variablen

int imageSize = 100; 
double dpi = 96; 
int width = 128; 
int height = 128; 
byte[] pixels = new byte[width * height * 3]; 

//Create my image.... 

for (int i = 0; i < imageSize; i++) 
{ 
    for (int j = 0; j < imageSize; j++) 
      { 
       int ct = myImage[i, j]; 

       pixels[i * imageSize * 3 + j + 0] = (byte)((ct % 16) * 14); 
       pixels[i * imageSize * 3 + j + 1] = (byte)((ct % 32) * 7); 
       pixels[i * imageSize * 3 + j + 2] = (byte)((ct % 128) * 2); 

      } 
}//end for 

     //Create the bitmap 
     BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgr24, null, pixels, width); 

Ich verstehe, dass ich nicht richtig die Pixel-Array nach oben setze. Irgendwelche Gedanken?

+0

Was ist 'imageSize' und warum Sie, dass anstelle von' width' und 'height' verwenden? –

+0

Ich habe es hinzugefügt, es in meiner ersten Kopie/Paste verpasst. imageSize = 100; –

+0

Ich vermute, dass Ihre Mathematik inkorrekt ist. Überlegen Sie, was "[i * imageSize * 3 + j + 1]" für eine bestimmte "i"/"j" -Kombination gleich ist. Dann bedenke, was "[i * imageSize * 3 + j + 0]" gleich ist, wenn "j" um eins höher ist. –

Antwort

3

für das Argument die Meldung „Wert nicht innerhalb des erwarteten Bereichs“ dass HRESULT.Check wirft eine WIC-Funktion, wenn (die native API zugrunde liegende WPF-Imaging-Funktionalität) gibt WINCODEC_ERR_INVALIDPARAMETER zurück.

In diesem Fall ist das Problem, dass der letzte Parameter BitmapSource.Create sollte die „Schrittlänge“ des Bitmaps (nicht die Breite) sein. Der "Schritt" einer Bitmap ist die (ganzzahlige) Anzahl von Bytes, die zum Speichern jeder Zeile der Bitmap erforderlich sind. Gemäß this MSDN magazine article ist die allgemeine Formel zum Berechnen des Schritts stride = (width * bitsPerPixel + 7)/8;. Bei einer 24-Bit-Bitmap vereinfacht sich dies auf width * 3.

Um die Ausnahme, übergeben Sie in der richtigen Schrittwert zu verhindern:

BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgr24, null, pixels, width * 3); 
1

Hier einige Code, den ich verwenden, wenn sie mit Bitmaps arbeiten ...

private const int cRedOffset = 0; 
private const int cGreenOffset = 1; 
private const int cBlueOffset = 2; 
private const int cAlphaOffset = 3; 

var width = bmp.Width; 
var height = bmp.Height; 
var data = bmp.LockBits(Rectangle.FromLTRB(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); 
var stride = data.Stride; 
var pixels = new byte[height * stride]; 

Marshal.Copy(data.Scan0, pixels, 0, height * stride); 

for (var row = 0; row < height; row++) 
{ 
    for (var col = 0; col < width; col++) 
    { 
     var pixel = (row * stride) + (col * 4); 
     var red = pixels[pixel + cRedOffset]; 
     var green = pixels[pixel + cGreenOffset]; 
     var blue = pixels[pixel + cBlueOffset]; 
     var alpha = pixels[pixel + cAlphaOffset]; 
    } 
}