C#Bitmap GetPixel(),GPU中的SetPixel()

Md *_*lam 9 c# gpgpu image bitmap cudafy.net

我使用Cudafy作为c#包装器我需要获取InputBitmap0.GetPixel(x, y)位图的颜色信息并为输出创建一个新的位图.

我需要在GPU中完成以下工作.

在CPU中

OutputBitmap.SetPixel(object_point_x, object_point_y, InputBitmap0.GetPixel(x, y));
Run Code Online (Sandbox Code Playgroud)

简而言之:

如何为输出Bitmap的每个像素点获取GetPixel(),为GPU中的outputbitmap Bitmap的每个像素点设置SetPixel().

Md *_*lam 5

OutputBitmap.SetPixel(object_point_x,object_point_y,InputBitmap0.GetPixel(x,y))

这需要时间,但最后,我破了我的情况.

我们有两个Bitmap:一个用于输出OutputBitmap,另一个用于输入InputBitmap0

让我们把这个任务分成几部分:

  1. 这样做InputBitmap0.GetPixel()x,y坐标
  2. 那么,OutputBitmap.SetPixel()对于不同的坐标object_point_x, object_point_y

Cudafy不支持BitmapColor输入数据.所以我将Bitmaps转换为byte类型.

BitmapData InputBitmapData0 = InputBitmap0.LockBits(new Rectangle(0, 0, InputBitmap0.Width, InputBitmap0.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

IntPtr ptr0 = InputBitmapData0.Scan0;//pointer for color

int stride0 = InputBitmapData0.Stride;

byte[]  input_ragba_color = new byte[InputBitmapData0.Stride * InputBitmap0.Height];

Marshal.Copy(ptr0, input_ragba_color, 0, bytes0);// Copy the RGB values of color value into the array.
Run Code Online (Sandbox Code Playgroud)

我们已将数据的内容复制InputBitmap0rgbValues数组中.现在我们需要做GetPixel()(得到R,G,B,A的值)的工作.

我们也需要做上面的工作(make array),OutputBitmap因为我们将SetPixel()在GPU中进行,但是我们稍后会将数据复制回位图.

BitmapData OutputBitmapData = OutputBitmap.LockBits(new Rectangle(0, 0, OutputBitmap.Width, OutputBitmap.Height), ImageLockMode.WriteOnly, OutputBitmap.PixelFormat);
IntPtr ptr_output = OutputBitmapData.Scan0;

byte[] output_ragba = new byte[OutputBitmapData.Stride * OutputBitmap.Height]; 
Run Code Online (Sandbox Code Playgroud)

它的GPU计算时间.让我们初始化gpu.

CudafyModule km = new CudafyTranslator.Cudafy();
GPGPU gpu = new CudafyHost.getDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
Run Code Online (Sandbox Code Playgroud)

现在发送input_ragba_color,并output_ragba给GPU,因为我们可以遍历数组和做任何计算.

byte[] dev_output_rgba_color = gpu.Allocate<byte>(output_ragba.Length);
byte[] dev_input_ragba_color = gpu.CopyToDevice(input_ragba_color);
gpu.Launch(N, 1).update_bitmap(x, y, object_point_x, object_point_y,int stride0, int OutputBitmapData.Stride,dev_input_ragba_color,dev_output_rgba_color);
Run Code Online (Sandbox Code Playgroud)

现在内部GPU(内核)

[Cudafy]
public static void update_bitmap(GThread thread, int x,int y,int object_point_x,int  object_point_y,int stride0, int OutputBitmapData_Stride,byte [] dev_input_ragba_color,byte [] dev_output_rgba_color)
{
   dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)];  
   dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 1] = input_ragba_color[(y * stride0) + (x * 4) + 1];
   dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 2] = input_ragba_color[(y * stride0) + (x * 4) + 2];
   dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4) + 3] = input_ragba_color[(y * stride0) + (x * 4) + 3];

}
Run Code Online (Sandbox Code Playgroud)

我正在考虑每个R,G,B,A,ex的值:input_ragba_color[(y * stride0) + (x * 4) + 1]这是解决第一个任务(InputBitmap0.GetPixel())

dev_output_rgba_color正在采用input_ragba_color 示例的值:

dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)]; 
Run Code Online (Sandbox Code Playgroud)

这解决了我们的第二个任务(OutputBitmap.SetPixel())

我们现在知道gpu dev_output_rgba_color为我们填充了一个array()OutputBitmap.

gpu.CopyFromDevice(dev_output_rgba_color, output_ragba);   //dev_output_rgba_color values will be assigned to output_ragba
gpu.FreeAll();
Run Code Online (Sandbox Code Playgroud)

将结果复制回OutputBitmap使用内存指针并从内存中解锁.

Marshal.Copy(output_ragba, 0, ptr_output, output_bytes);// Copy the RGB values of color value into the array.
OutputBitmap.UnlockBits(OutputBitmapData);
Run Code Online (Sandbox Code Playgroud)

现在OutputBitmap包含更新的值.