c++ - 如何将 System::Drawing::Image^ 转换为无符号字符

标签 c++ .net winforms clr picturebox

我需要在 winforms 中将 Image^ 转换为 unsigned char 以实现去拜耳功能。
代码:

void ConvertBayer8ToBGR(VmbUchar_t* bayerImgDat, VmbUchar_t* bgrOutputDat)
{
VmbUchar_t* newimagedata_start = bgrOutputDat;

int currentTempIndex = 0;
int nearestBluesAvg = 0;
int nearestRedsAvg = 0;
int nearestGreensAvg = 0;

for(int j = 0; j < 1100; j++)
{
    for(int i = 0; i < 2752; i++) //G R G R G... 
    {
        if(currentTempIndex % 2 == 0 /* even, green */)
        {
            //avg blue
            if(j == 0) //if in the first row, only take next blue
            {
                nearestBluesAvg = *(bayerImgDat+currentTempIndex+2752);
            }
            else
            {
                nearestBluesAvg = (*(bayerImgDat + currentTempIndex + 2752) + *(bayerImgDat+currentTempIndex-2752)) / 2;
            }
            *bgrOutputDat = nearestBluesAvg; //b
            bgrOutputDat++;
            *bgrOutputDat = *(bayerImgDat + currentTempIndex); //g
            bgrOutputDat++;
            //avg red
            if(i == 0) //if in first column, only take next red 
            {
                nearestRedsAvg = *(bayerImgDat+currentTempIndex+1);
            }
            else
            {
                nearestRedsAvg = ( (*(bayerImgDat+currentTempIndex+1)) + (*(bayerImgDat+currentTempIndex-1)) ) / 2;
            }
            *bgrOutputDat = nearestRedsAvg; //r
            bgrOutputDat++;

            currentTempIndex++;
        }
        else /* odd, red*/
        {
            //avg blue
            if(i == 1099) //if in last column, take just left-down blue pixel
            {
                nearestBluesAvg = *(bayerImgDat+currentTempIndex-1+2752);
            }
            else // else take both left-down and right-down
            {
                nearestBluesAvg = (*(bayerImgDat+currentTempIndex+1+2752) + *(bayerImgDat+currentTempIndex-1+2752)) / 2;
            }
            *bgrOutputDat = nearestBluesAvg; //b
            bgrOutputDat++;
            //avg green
            nearestGreensAvg = (*(bayerImgDat+currentTempIndex-1) + *(bayerImgDat+currentTempIndex+2752)) / 2;
            *bgrOutputDat = nearestGreensAvg;  //g
            bgrOutputDat++;
            *bgrOutputDat = *(bayerImgDat + currentTempIndex); //r
            bgrOutputDat++;

            currentTempIndex++;
        }
    }
    for(int i = 0; i < 2752; i++)//B G B G B G B....
    {
        if(currentTempIndex % 2 == 0 /* even, blue */)
        {

            *bgrOutputDat = *(bayerImgDat + currentTempIndex); //b
            bgrOutputDat++;
            //avg green
            nearestGreensAvg = (*(bayerImgDat + currentTempIndex + 1) + *(bayerImgDat + currentTempIndex -2752)) / 2;
            *bgrOutputDat = nearestGreensAvg; //g
            bgrOutputDat++;
            //avg red
            if(i == 0) //if first column, take only right-up pixel
            {
                nearestRedsAvg = *(bayerImgDat+currentTempIndex+1-2752);
            }
            else //else take both left-up and right-up pixels
            {
                nearestRedsAvg = (*(bayerImgDat+currentTempIndex-1-2752) + *(bayerImgDat+currentTempIndex+1-2752)) / 2;
            }
            *bgrOutputDat = nearestRedsAvg; //r
            bgrOutputDat++;

            currentTempIndex++;

        }
        else /* odd, green*/
        {
            //avg blue
            if(i == 2751) //if in last column, only take previous blue (next blue doesnt exist)
            {
                nearestBluesAvg = *(bayerImgDat + currentTempIndex - 1);
            }
            else //else take both next and previous
            {
                nearestBluesAvg = (*(bayerImgDat+currentTempIndex+1) + *(bayerImgDat+currentTempIndex-1)) / 2;
            }
            *bgrOutputDat = nearestBluesAvg; //b
            bgrOutputDat++;
            *bgrOutputDat = *(bayerImgDat + currentTempIndex); //g
            bgrOutputDat++;
            //avg red
            if(j == 1099) //if in last row, only take previous red (next red doesn't exist)
            {
                nearestRedsAvg = *(bayerImgDat+currentTempIndex-2752);
            }
            else //else take both
            {
                nearestRedsAvg = (*(bayerImgDat+currentTempIndex+2752) + *(bayerImgDat+currentTempIndex-2752)) / 2;
            }
            *bgrOutputDat = nearestRedsAvg; //r
            bgrOutputDat++;

            currentTempIndex++;
        }
    }
}


bgrOutputDat = newimagedata_start;

谁能帮我将 Image^ 转换为 unsigned char,或者重写此函数以使用 Image^ 作为输入?

谢谢, 安德鲁

最佳答案

您需要访问位图中的像素数据。使用 Image 执行此操作的最佳方法是在 Bitmap 子类上使用 LockBits 方法。像这样的东西(假设你的 Image 实际上是一个 Bitmap):

auto bmp = dynamic_cast<Bitmap^>(image);
Rectangle rect(0, 0, bmp->Width, bmp->Height);
auto bmpData = bm->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadOnly);
VmbUchar_t* bayerImgDat = reinterpret_cast<VmbUchar_t*>(bmpData->Scan0.ToPointer());
VmbUchar_t* bgrOutputDat = // need to allocate
ConvertBayer8ToBGR(bayerImgDat, bgrOutputDat);

关于c++ - 如何将 System::Drawing::Image^ 转换为无符号字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37928249/

相关文章:

c++ - 如何阻止和唤醒 boost 线程?

c# - 了解没有线程的异步/等待

c# - 在应用程序中重命名树节点时重命名文件夹名称

c# - 在 Telerik RadGrid for Winforms 中选择包括折叠组在内的多行

c++ - OpenGL + libpng : wrong colors on image

c++ - 为 Mac 生成机器特定的 key

.net - 无法显示错误消息,因为找不到包含它的可选资源程序集

c# - 如何在 .NET 中使用自定义格式对 TimeSpan 对象进行 String.Format ?

c# - Windows 窗体中的控件不显示工具提示气球

c++ - vector 初始化 vector