OutputBitmap.SetPixel(object_point_x, object_point_y, InputBitmap0.GetPixel(x, y))
It took time but finally, I , cracked my case.
We have two Bitmap
: one for output OutputBitmap
and another for input InputBitmap0
Lets divide this task into parts:
- do
InputBitmap0.GetPixel()
for x
,y
coordinate
- then ,
OutputBitmap.SetPixel()
for a different coordinate object_point_x, object_point_y
Cudafy does not support Bitmap
or Color
type data. So I converted the Bitmaps to byte
type.
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.
We have copied the content of the InputBitmap0
to the rgbValues
array. Now we need to do the work of GetPixel()
(get the values of R,G,B,A).
We need to do the above work ( make array) for OutputBitmap
too because we will be doing SetPixel()
in GPU but we will copy the array back to the bitmap later.
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];
Its GPU time for calculation. Lets initialize gpu.
CudafyModule km = new CudafyTranslator.Cudafy();
GPGPU gpu = new CudafyHost.getDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
Now send input_ragba_color
and output_ragba
to the gpu because we can iterate the array and do any calculation.
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);
Now inside GPU(kernel)
[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];
}
I am taking values of each R,G,B,A ,ex: input_ragba_color[(y *
stride0) + (x * 4) + 1]
which is solving 1st task
(InputBitmap0.GetPixel()
)
dev_output_rgba_color
is taking the values of input_ragba_color
example:
dev_output_rgba_color[(object_point_y * OutputBitmapData_Stride) + (object_point_x * 4)] = input_ragba_color[(y * stride0) + (x * 4)];
which is solves our 2nd task (OutputBitmap.SetPixel()
)
We now know that gpu has populated an array(dev_output_rgba_color
) for our OutputBitmap
.
gpu.CopyFromDevice(dev_output_rgba_color, output_ragba); //dev_output_rgba_color values will be assigned to output_ragba
gpu.FreeAll();
Copy the result back to the OutputBitmap
using the memory pointer and unlock it from the memory.
Marshal.Copy(output_ragba, 0, ptr_output, output_bytes);// Copy the RGB values of color value into the array.
OutputBitmap.UnlockBits(OutputBitmapData);
Now the OutputBitmap
contains the updated values.