将像素写入新的可写位图

时间:2015-05-21 15:55:50

标签: c# wpf pixel writeablebitmap

程序执行此操作https://www.youtube.com/watch?v=l1_WmoiKgPg仅视频的前50秒完成第二个标签:) 所以基本上你选择最红的颜色然后如果它等于最绿,那么最蓝。 但新的像素没有写入新图像为什么? 以及如何用随机类做第一个单选按钮?

我的自定义方法:

private void writepixel(WriteableBitmap ElWriteableBitmap, int iCoordX, int iCoordY, byte bRojo, byte bVerde, byte bAzul, byte bAlfa)
{
    unsafe
    {
        int ipTempBackBuffer = (int)ElWriteableBitmap.BackBuffer;
        ipTempBackBuffer += iCoordY * ElWriteableBitmap.BackBufferStride;
        ipTempBackBuffer += iCoordX * 4;

        int color_data = bAlfa << 24; // Canal alfa
        color_data |= bRojo << 16; // Componente rojo
        color_data |= bVerde << 8; // Componente verde
        //color_data = color_data & (bVerde << 8);
        color_data |= bAzul << 0;  // Componente azul 

        *((int*)ipTempBackBuffer) = color_data;
    }
}

private System.Windows.Media.Color readPixel(WriteableBitmap ElWriteableBitmap, int iCoordX, int iCoordY)
{
    System.Windows.Media.Color colorResultante = new System.Windows.Media.Color();
    unsafe
    {
        int ipTempBackBuffer = (int)ElWriteableBitmap.BackBuffer;
        ipTempBackBuffer += iCoordY * ElWriteableBitmap.BackBufferStride;
        ipTempBackBuffer += iCoordX * 4;

        colorResultante.A = ((byte*)ipTempBackBuffer)[3];
        colorResultante.R = ((byte*)ipTempBackBuffer)[2];
        colorResultante.G = ((byte*)ipTempBackBuffer)[1];
        colorResultante.B = ((byte*)ipTempBackBuffer)[0];
    }
    return colorResultante;
}

上传了2张图片

private void Button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.FileName = "Imagen";
    ofd.DefaultExt = ".bmp";
    ofd.Filter = "Mapas de bits|*.bmp";
    Nullable<bool> result = ofd.ShowDialog();
    if (result == true)
    {
        BitmapImage bmpi = new BitmapImage(); //JpegBitmapEncoder alternativa
        bmpi.BeginInit();
        bmpi.UriSource = new Uri(ofd.FileName);
        bmpi.EndInit();
        m_wbmpLaImagen = new WriteableBitmap(bmpi);
        laimagen1.Source = m_wbmpLaImagen;
    }
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.FileName = "Imagen";
    ofd.DefaultExt = ".bmp";
    ofd.Filter = "Mapas de bits|*.bmp";
    Nullable<bool> result = ofd.ShowDialog();
    if (result == true)
    {
        BitmapImage bmpi = new BitmapImage(); //JpegBitmapEncoder alternativa
        bmpi.BeginInit();
        bmpi.UriSource = new Uri(ofd.FileName);
        bmpi.EndInit();
        m_wbmpLaImagen = new WriteableBitmap(bmpi);
        laimagen2.Source = m_wbmpLaImagen;
    }
}

我的随机类和两个单选按钮的代码:

private static int[] randomNumber()
{
    Random rand = new Random();
    int[] nums = new int[20];
    for (int x = 0; x < 1; x++)
    {
        nums[x] = rand.Next();
    }
    return nums;
}

private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
    WriteableBitmap imagen1bmp;
    WriteableBitmap imagen2bmp;
    WriteableBitmap imgcom;
    imgcom = (WriteableBitmap)imgcombined.Source;
    int x, y;
    Color col3 = new Color();
    imagen1bmp = (WriteableBitmap)laimagen1.Source;
    imagen2bmp = (WriteableBitmap)laimagen2.Source;        

    for (y = 0; y < imagen1bmp.Height; y++)
    {
        for (x = 0; x < imagen1bmp.Width; x++)
        {
            // Get both colors in the pixel point
            Color col1 = readPixel(imagen1bmp, x, y);
            Color col2 = readPixel(imagen2bmp, x, y);
            // the color for the output image for this pixel
            if (col1.R > col2.R)
                col3.R = col1.R;
            else
                col3.R = col2.R;
            if (col1.G > col2.G)
                col3.G = col1.G;
            else
                col3.G = col2.G;

            if (col1.B > col2.B)
                col3.B = col1.B;
            else
                col3.B = col2.B;

            if (col1.A > col2.A)
                col3.A = col1.A;
            else
                col3.A = col2.A;

            writepixel(imgcom, x, y, col3.R, col3.G, col3.B, col3.A);
        }
        UpdateLayout();
    }
    UpdateLayout();
}

1 个答案:

答案 0 :(得分:0)

您的代码中有四个错误:

错误1 imgcom未使用正确尺寸的新位图进行实例化。解决方案:

imgcom = new WriteableBitmap(imagen1bmp);
// Make changes...
imgcombined.Source = imgcom;

错误2 )循环使用的是显示像素尺寸(WidthHeight),而不是内部缓冲区尺寸(PixelWidth和{{1 }})。解决方案:

PixelHeight

错误3 )目标缓冲区未在写入时被锁定和解锁。解决方案:

 for (y = 0; y < imagen1bmp.PixelHeight; y++)
 for (x = 0; x < imagen1bmp.PixelWidth; x++)

错误4 )缓冲区的偏移量是使用 imgcom.Lock(); // Change the pixels... imgcom.Unlock(); 和缓冲区的BackBufferStride指针。这是不正确的,因为缓冲区步幅是指字节数,而不是像素。解决方案:

int

功能结果

 ipTempBackBuffer += (iCoordY * ElWriteableBitmap.PixelWidth) + iCoordX;