首页 > 解决方案 > 我的简单 Lockbits Image 类中有一个错误

问题描述

我有这个简单的类来在图像上绘制点。限制为 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;
        }
    }

标签: c#imagergblockbits

解决方案


推荐阅读