【问题标题】:How did I get a Stride less than the Bitmap width?我如何获得小于位图宽度的步幅?
【发布时间】:2012-09-26 14:22:13
【问题描述】:

我正在从一个 1bpp 位图复制到一个较小的 1bpp 位图。我只想剪掉一个区域,这样我就可以计算黑色像素的数量了。

我使用以下方法制作副本:

    private Bitmap Copy(Bitmap srcBitmap, Rectangle section)
    {
        BitmapData SourceLockedData;
        BitmapData DestLockedData;
        Rectangle DestRect;
        byte[] SrcImageData;
        byte[] DestImageData;
        int ByteCount;
        int WidthCount = 0;
        int CurrentLine = 0;
        int DestStride;
        int SrcStride = 0;

        // Create the new bitmap and associated graphics object
        Bitmap Newbmp = new Bitmap(section.Width, section.Height, PixelFormat.Format1bppIndexed);
        Newbmp.SetResolution(srcBitmap.HorizontalResolution, srcBitmap.VerticalResolution);

        //Lock the bits
        SourceLockedData = srcBitmap.LockBits(section, ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);

        SrcStride = SourceLockedData.Stride;

        //Get a count of the number of bytes to copy. Remember, bytes are not pixels.
        ByteCount = SourceLockedData.Stride * SourceLockedData.Height;

        //Initialize the source byte array
        SrcImageData = new byte[ByteCount];

        //Copy the data to the source byte array
        Marshal.Copy(SourceLockedData.Scan0, SrcImageData, 0, ByteCount);

        //Unlock the bits
        srcBitmap.UnlockBits(SourceLockedData);

        //Set a rectangle to the size of the New bitmap
        DestRect = new Rectangle(new Point(0, 0), Newbmp.Size);

        //Lock the bits
        DestLockedData = Newbmp.LockBits(DestRect, ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);

        DestStride = DestLockedData.Stride;

        //Get a count of the number of bytes to copy. Remember, bytes are not pixels.
        ByteCount = DestLockedData.Stride * DestLockedData.Height;

        //Initialize the source byte array
        DestImageData = new byte[ByteCount];

        //Copy the data to the destination byte array
        Marshal.Copy(DestLockedData.Scan0, DestImageData, 0, ByteCount);

        //Unlock for now
        Newbmp.UnlockBits(DestLockedData);

        for (int ArrayIndex = 0; ArrayIndex < ByteCount; ArrayIndex++)
        {
            if (WidthCount == Newbmp.Width)
            {
                //increment the line and push the index by the stride
                ArrayIndex = (++CurrentLine) * DestStride;
                continue;
            }

            DestImageData[ArrayIndex] = SrcImageData[ArrayIndex];
            WidthCount++;
        }

        //Lock the bits again
        DestLockedData = Newbmp.LockBits(DestRect, ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);

        //Copy data from byte array to IntPtr
        Marshal.Copy(DestImageData, 0, DestLockedData.Scan0, ByteCount);

        //Unlock bits
        Newbmp.UnlockBits(DestLockedData);

        // Return the bitmap
        return Newbmp;
    }

我遇到的最大问题是 SourceLockedData.Stride 和 DestLockedData.Stride 都小于各自图像的宽度。这个怎么可能?根据我对跨度的了解,它是从一条数据扫描线到下一条数据扫描线的位数。这在数学上怎么可能小于宽度?

我是否使用了 LockBits 或 BitmapData 错误? BitmapData 不能被信任吗?我应该手动计算步幅吗?

汤姆·P.

【问题讨论】:

  • Stride 不是 bytes 而不是 bits 的数量吗?

标签: c# image-processing bitmapdata


【解决方案1】:

我发现如果您正在处理 RLE 位图,步幅可以小于宽度。因为我加载的位图是 TIFF,所以它们是 RLE8 编码的。

【讨论】:

  • 如果你有任何形式的压缩,那么你根本不能依赖恒定的步幅。
  • 您没有对 1bpp 图像进行 RLE8 压缩,它仅用于 8bpp 图像。步幅以字节为单位,而不是位,简单地解释了为什么它小于 1bpp 图像的宽度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多