簡體   English   中英

2D數組中的C#位圖

[英]C# bitmap from 2D Array

我正在嘗試從2D數組構建位圖,且其尺寸較小,僅用於測試。 即使我正確設置了矩陣(一個像素黑,一個白色),在構建位圖時,似乎也應用了一些插值濾波器。 如何獲取像素值?

bool switchColor = false;
int width = 30;
int height = 15;
int stride = width * 4;
int[,] integers = new int[width, height];

int thres = 0;
for (int i = 0; i < width; ++i)
{
    for (int j = 0; j < height; ++j)
    {                        
        if (switchColor) 
        {
            switchColor = false;
            thres = 0;
        }
        else 
        { 
            switchColor = true;
            thres = 255;
        }
        byte[] bgra = new byte[] { (byte)(thres), (byte)(thres), (byte)(thres), 255 };
        integers[i, j] = BitConverter.ToInt32(bgra, 0);
    }
}

// Copy into bitmap
Bitmap bitmap;
unsafe
{
    fixed (int* intPtr = &integers[0, 0])
    {
        bitmap = new Bitmap(width, height, stride, PixelFormat.Format32bppRgb, new IntPtr(intPtr)); 
        pictureBox1.Image = bitmap;                                         
    }
}

我有:

在此處輸入圖片說明

我認為這只是在拉伸模式下放大圖片框時的預期行為。 您只創建了一個30x15的小位圖,我認為它比設計器中的PictureBox小。 嘗試設置:

pictureBox1.SizeMode = PictureBoxSizeMode.Normal;

然后要獲得測試的更大視圖,您可以按比例放大測試圖像:

int width = 300;
int height = 150;

一般來說,您嘗試執行的操作存在很多問題...

  • 圖像不使用2D數組; 他們使用一維數組,並且要制作圖像,您也應該這樣做。 如果您有2D數組,請將其轉換為逐行1D字節數組,以便將其用作使用LockBits構建圖像的源。
  • 原始指針是一件可怕的事情。 鑒於它們是不受管的事實,每當垃圾回收器確定您可能不再需要該字節數組時,您的映像可能就會混亂。 使用LockBitsMarshal.Copy正確填充圖像。
  • 循環遍歷圖像的內容時,通常會逐行工作,因為這是將圖像數據保存在其一維數組中的方式。 您的外循環是寬度,內循環是高度,因此,由於內循環是按順序遍歷直接數據的循環,因此您將逐列循環。 簡單地命名您的實際循環變量xy已經可以消除很多混亂。
  • 如果您將數據解釋為RGB,則無需將第4個字節設置為255。 它只是填充,而不是alpha。
  • 實際上,您不需要整個數組操作。 您可以只使用現有的Color.WhiteColor.Black ,並使用它們的ToArgb()函數獲取其Int32值。 而且由於您僅在此處使用兩個值,因此將它們預先存儲在兩個Int32變量中會更簡單。

除此之外,您真正的問題只是圖片框上設置的平滑縮放。 您可以通過使PictureBox的子類重寫OnPaint函數來解決此問題,在該子類中,您將圖形對象設置為使用InterpolationMode.NearestNeighbor

public class PixelBox : PictureBox
{
    protected override void OnPaint (PaintEventArgs pe)
    {
        pe.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
        // Either the docs on this are wrong, or it behaves differently in NearestNeighbor.
        // putting it to Half makes it NOT shift the whole thing up and to the left by half a (zoomed) pixel.
        pe.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
        base.OnPaint(pe);
    }
}

而且, 作為EHZ說 ,你可能只是想放大。 若要查看最終結果,請保存代碼中的圖像,而不要在拉伸它的控件上使用打印屏幕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM