Guten Morgen.
Ich arbeite derzeit an einer eigenen DrawImage-Funktion mit LockBits. Ich erhoffe mir von Ihr einen schnelleren Zeichenvorgang als mit Graphics.DrawImage. Um ein Bild auf ein anderes zu zeichnen übertrage Ich jedes Pixel einzeln, aber das Ergebnis ist irgendwie nicht das, was Ich mir erhofft hatte. Hier ist mal der Quellcode:
BitmapGraphics (für die Pixeloperationen mit LockBits auf einem Bitmap)
Die Anwendung
Was eigentlich rauskommen sollte, sieht so aus:
Was jedoch rauskam sieht so aus:
Bin schon im Einzelschritt komplett durchgesteppt, aber finde den Fehler nicht. Könnt Ihr mir da bitte helfen?
LG
~ides
Ich arbeite derzeit an einer eigenen DrawImage-Funktion mit LockBits. Ich erhoffe mir von Ihr einen schnelleren Zeichenvorgang als mit Graphics.DrawImage. Um ein Bild auf ein anderes zu zeichnen übertrage Ich jedes Pixel einzeln, aber das Ergebnis ist irgendwie nicht das, was Ich mir erhofft hatte. Hier ist mal der Quellcode:
Code von codeproject.com/Tips/240428/Wo…bitmap-faster-with-Csharp
C#-Quellcode
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
- namespace WindowsFormsApplication1
- {
- public class BitmapGraphics
- {
- Bitmap source = null;
- IntPtr Iptr = IntPtr.Zero;
- BitmapData bitmapData = null;
- public byte[] Pixels { get; set; }
- public int Depth { get; private set; }
- public int Width { get; private set; }
- public int Height { get; private set; }
- public BitmapGraphics(Bitmap source)
- {
- this.source = source;
- }
- /// <summary>
- /// Lock bitmap data
- /// </summary>
- public void LockBits()
- {
- try
- {
- // Get width and height of bitmap
- Width = source.Width;
- Height = source.Height;
- // get total locked pixels count
- int PixelCount = Width * Height;
- // Create rectangle to lock
- Rectangle rect = new Rectangle(0, 0, Width, Height);
- // get source bitmap pixel format size
- Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
- // Check if bpp (Bits Per Pixel) is 8, 24, or 32
- if (Depth != 8 && Depth != 24 && Depth != 32)
- {
- throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
- }
- // Lock bitmap and return bitmap data
- bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
- source.PixelFormat);
- // create byte array to copy pixel values
- int step = Depth / 8;
- Pixels = new byte[PixelCount * step];
- Iptr = bitmapData.Scan0;
- // Copy data from pointer to array
- Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// Unlock bitmap data
- /// </summary>
- public void UnlockBits()
- {
- try
- {
- // Copy data from byte array to pointer
- Marshal.Copy(Pixels, 0, Iptr, Pixels.Length);
- // Unlock bitmap data
- source.UnlockBits(bitmapData);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// Get the color of the specified pixel
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <returns></returns>
- public Color GetPixel(int x, int y)
- {
- Color clr = Color.Empty;
- // Get color components count
- int cCount = Depth / 8;
- // Get start index of the specified pixel
- int i = ((y * Width) + x) * cCount;
- if (i > Pixels.Length - cCount)
- throw new IndexOutOfRangeException();
- if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha
- {
- byte b = Pixels[i];
- byte g = Pixels[i + 1];
- byte r = Pixels[i + 2];
- byte a = Pixels[i + 3]; // a
- clr = Color.FromArgb(a, r, g, b);
- }
- if (Depth == 24) // For 24 bpp get Red, Green and Blue
- {
- byte b = Pixels[i];
- byte g = Pixels[i + 1];
- byte r = Pixels[i + 2];
- clr = Color.FromArgb(r, g, b);
- }
- if (Depth == 8)
- // For 8 bpp get color value (Red, Green and Blue values are the same)
- {
- byte c = Pixels[i];
- clr = Color.FromArgb(c, c, c);
- }
- return clr;
- }
- /// <summary>
- /// Set the color of the specified pixel
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="color"></param>
- public void SetPixel(int x, int y, Color color)
- {
- // Get color components count
- int cCount = Depth / 8;
- // Get start index of the specified pixel
- int i = ((y * Width) + x) * cCount;
- if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha
- {
- Pixels[i] = color.B;
- Pixels[i + 1] = color.G;
- Pixels[i + 2] = color.R;
- Pixels[i + 3] = color.A;
- }
- if (Depth == 24) // For 24 bpp set Red, Green and Blue
- {
- Pixels[i] = color.B;
- Pixels[i + 1] = color.G;
- Pixels[i + 2] = color.R;
- }
- if (Depth == 8)
- // For 8 bpp set color value (Red, Green and Blue values are the same)
- {
- Pixels[i] = color.B;
- }
- }
- }
- }
C#-Quellcode
- private void Form1_Load(object sender, EventArgs e)
- {
- Bitmap bmp = new Bitmap(50, 50);
- using (Graphics g = Graphics.FromImage(bmp))
- {
- g.Clear(Color.Red);
- }
- Bitmap tzg = new Bitmap(100, 100);
- using (Graphics g = Graphics.FromImage(tzg))
- {
- g.Clear(Color.Black);
- }
- tzg = DrawImage(bmp, tzg, new Point(10, 10));
- pictureBox1.Image = tzg;
- }
- private Bitmap DrawImage(Bitmap sourceImage, Bitmap destinationImage, Point location)
- {
- BitmapGraphics bg = new BitmapGraphics(sourceImage);
- BitmapGraphics bgx = new BitmapGraphics(destinationImage);
- int cx = location.X;
- int cy = location.Y;
- bg.LockBits();
- bgx.LockBits();
- //Jedes Pixel auf dem sourceImage durchgehen und auf dem destinationImage an der Position cx, cy zeichnen
- for (int x = 0; x < sourceImage.Width; x++)
- {
- for (int y = 0; y < sourceImage.Height; y++)
- {
- if (cx >= destinationImage.Width) continue;
- if (cy >= destinationImage.Height) continue;
- bgx.SetPixel(cx, cy, bg.GetPixel(x, y));
- cy++;
- }
- cx++;
- }
- bg.UnlockBits();
- bgx.UnlockBits();
- return destinationImage;
- }
Was eigentlich rauskommen sollte, sieht so aus:
Was jedoch rauskam sieht so aus:
Bin schon im Einzelschritt komplett durchgesteppt, aber finde den Fehler nicht. Könnt Ihr mir da bitte helfen?
LG
~ides