我有这个简单的类来在图像上绘制点。限制为 24bbp。但是在某些宽度下,图像会中断,颜色会失真,并且图像会向右移动,并在图像中向下移动。只有当宽度是 4 的倍数时它才正确,我不知道为什么。有人可以指出我的错误吗?多谢你们。 问题示例
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using static System.Math;
public class TImage
{
private readonly Bitmap source = null;
private IntPtr Iptr = IntPtr.Zero;
private BitmapData bitmapData = null;
private bool locked = false;
private readonly int PixelCount;
private byte[] pixels;
public int Width { get; private set; }
public int Height { get; private set; }
public TImage(int width, int height)
{
source = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Width = width; Height = height;
PixelCount = Width * Height;
}
public TImage(Bitmap image)
{
if (image.PixelFormat != PixelFormat.Format24bppRgb) throw new FormatException("Only 24bppRgb can be used");
source = image;
Width = source.Width; Height = source.Height;
PixelCount = Width * Height;
}
private void Lock()
{
if (!locked)
{
Rectangle rect = new Rectangle(0, 0, Width, Height);
bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
// create byte array to copy pixel values
pixels = new byte[PixelCount * 3];
Iptr = bitmapData.Scan0;
// Copy data from pointer to array
Marshal.Copy(Iptr, pixels, 0, pixels.Length);
locked = true;
}
}
private void Unlock()
{
if (locked)
{
Marshal.Copy(pixels, 0, Iptr, pixels.Length);
source.UnlockBits(bitmapData);
locked = false;
}
}
public Color GetPixel(int x, int y)
{
if (!locked) Lock();
// Get start index of the pixel
int i = (y * Width + x) * 3;
if (i+2 > pixels.Length || i <0) throw new IndexOutOfRangeException();
byte b = pixels[i];
byte g = pixels[i + 1];
byte r = pixels[i + 2];
return Color.FromArgb(r, g, b);
}
public void SetPixel(int x, int y, Color color)
{
if (!locked) Lock();
int i = ((y * Width + x) * 3);
if (i + 2 < pixels.Length && i >= 0)
{
pixels[i] = color.B;
pixels[i + 1] = color.G;
pixels[i + 2] = color.R;
}
}
public void SetPixel(double x, double y, Color color)
{
SetPixel((int)Round(x), (int)Round(y), color);
}
public static implicit operator Bitmap(TImage img)
{
img.Unlock();
return img.source;
}
}