简体   繁体   中英

How did I get a Stride less than the Bitmap width?

I am copying from one 1bpp bitmap to a smaller 1bpp bitmap. I just want to clip out a region so I can count the number of black pixels.

I use the following to make the copies:

    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;
    }

The biggest problem I am having is that both the SourceLockedData.Stride and DestLockedData.Stride are smaller than the width of the respective images. How can that be? From everything I know about stride it's the number of bits from one scan line of data to the next scan line of data. How is it mathematically possible for this to be less than the width?

Am I using LockBits or BitmapData wrong? Can BitmapData not be trusted? Should I calculate the stride by hand?

Tom P.

I figured out that the stride can be less than the width if you are dealing with RLE bitmaps. Since the bitmaps that I am loading are TIFFs they are RLE8 encoded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM