位图操作 - 图像宽度减少1/4

时间:2016-03-31 09:42:49

标签: c# .net bitmap unsafe

我项目之前的那个人写了一些我试图理解的代码。我对C#并不擅长,但试着抓住它。

以下代码旨在对颜色值应用阈值,但现在我正在尝试简单地复制图像以查看所有图像处理的工作方式(这些部分仅由我自己删除)。

不幸的是,我的图像的1/4被简单地切断了。我试着阅读有关步幅,scan0但是找不到任何这种行为的原因。我希望这是由alpha通道引起的,所以我更改了以下代码

public unsafe Bitmap AdjustThreshold(int value)
{
    int maxX = _internalBitmapMemory.Width;
    int maxY = _internalBitmapMemory.Height;

    BitmapData bmpDataImage_1, bmpDataImage_2;
    Bitmap newBitmap = new Bitmap(_internalBitmapMemory.Width, _internalBitmapMemory.Height, _internalBitmapMemory.PixelFormat);

    bmpDataImage_1 = _internalBitmapMemory.LockBits(new Rectangle(0, 0, maxX, maxY), System.Drawing.Imaging.ImageLockMode.ReadOnly, _internalBitmapMemory.PixelFormat);
    bmpDataImage_2 = newBitmap.LockBits(new Rectangle(0, 0, maxX, maxY), System.Drawing.Imaging.ImageLockMode.WriteOnly, newBitmap.PixelFormat);

    byte* currentPtrImage_1 = (byte*)bmpDataImage_1.Scan0;
    byte* currentPtrImage_2 = (byte*)bmpDataImage_2.Scan0;

    int offsetImage_1 = bmpDataImage_1.Stride - maxX * 3;
    int offsetImage_2 = bmpDataImage_2.Stride - maxX * 3;

    // Color cNow; 

    for (int currentRow = 0; currentRow < newBitmap.Height; currentRow++)
    {
        for (int currentColumn = 0; currentColumn < newBitmap.Width; currentColumn++, currentPtrImage_1 += 3, currentPtrImage_2 += 3)
        {
            // cNow = Color.FromArgb(*(currentPtrImage_1), *(currentPtrImage_1 + 1), *(currentPtrImage_1 + 2));

            *(currentPtrImage_2) = *(currentPtrImage_1);
            *(currentPtrImage_2 + 1) = *(currentPtrImage_1 + 1);
            *(currentPtrImage_2 + 2) = *(currentPtrImage_1 + 2);

        }

        currentPtrImage_1 += offsetImage_1;
        currentPtrImage_2 += offsetImage_2;
    }

    _internalBitmapMemory.UnlockBits(bmpDataImage_1);
    newBitmap.UnlockBits(bmpDataImage_2);

    return newBitmap;
}

public unsafe Bitmap AdjustThreshold(int value)
{
    int maxX = _internalBitmapMemory.Width;
    int maxY = _internalBitmapMemory.Height;

    BitmapData bmpDataImage_1, bmpDataImage_2;
    Bitmap newBitmap = new Bitmap(_internalBitmapMemory.Width, _internalBitmapMemory.Height, _internalBitmapMemory.PixelFormat);

    bmpDataImage_1 = _internalBitmapMemory.LockBits(new Rectangle(0, 0, maxX, maxY), System.Drawing.Imaging.ImageLockMode.ReadOnly, _internalBitmapMemory.PixelFormat);
    bmpDataImage_2 = newBitmap.LockBits(new Rectangle(0, 0, maxX, maxY), System.Drawing.Imaging.ImageLockMode.WriteOnly, newBitmap.PixelFormat);

    byte* currentPtrImage_1 = (byte*)bmpDataImage_1.Scan0;
    byte* currentPtrImage_2 = (byte*)bmpDataImage_2.Scan0;

    int offsetImage_1 = bmpDataImage_1.Stride - maxX * 4;
    int offsetImage_2 = bmpDataImage_2.Stride - maxX * 4;

    // Color cNow; 

    for (int currentRow = 0; currentRow < newBitmap.Height; currentRow++)
    {
        for (int currentColumn = 0; currentColumn < newBitmap.Width; currentColumn++, currentPtrImage_1 += 4, currentPtrImage_2 += 4)
        {
            // cNow = Color.FromArgb(*(currentPtrImage_1), *(currentPtrImage_1 + 1), *(currentPtrImage_1 + 2));

            *(currentPtrImage_2) = *(currentPtrImage_1);
            *(currentPtrImage_2 + 1) = (byte)(*(currentPtrImage_1 + 1) / 2);
            *(currentPtrImage_2 + 2) = *(currentPtrImage_1 + 2);
            *(currentPtrImage_2 + 3) = *(currentPtrImage_1 + 3);
        }

        currentPtrImage_1 += offsetImage_1;
        currentPtrImage_2 += offsetImage_2;
    }

    _internalBitmapMemory.UnlockBits(bmpDataImage_1);
    newBitmap.UnlockBits(bmpDataImage_2);

    return newBitmap;
}

并发现它现在有效。

真正让我感到困惑的是:以前的代码是否有效,并且有任何理由说明为什么它对我不起作用,或者代码从未按预期工作但没有人发现过?!

我用32bbpARGB图像输入了该功能。如果我有不同的颜色部门会发生什么?根据我的理解,它会导致访问冲突,因为指针将超过位图缓冲区的最大值。如果我只是通过

创建一个新的位图
Bitmap myBitmap = new Bitmap(Width, Height);

将提供什么bbp?系统标准?

如果我会观察到不同颜色深度的可能性,我应该如何处理?我应该简单地改变给予32bbpARGB的任何位图的颜色深度吗?或者在这里建立的方式是什么?

感谢您输入:)

1 个答案:

答案 0 :(得分:1)

我将回答一个问题:

  

Bitmap myBitmap = new Bitmap(Width, Height);

     

将提供什么bbp?系统标准?

如果您选中Bitmap consctructor

  

此构造函数创建一个PixelFormat枚举值为Format32bppArgb的Bitmap。

  

指定格式为每像素32位;每个8位用于alpha,红色,绿色和蓝色组件。