не знаю что такое шарп 

 , но вывод - заменять цвет попиксельно.
проще всего - в БМП - там заголовок (повторяю - не помню какой, завтра скажу), там размер заголовка, смещение, где пикселы начинаются etc. 
найти где начались данные -  и заменить
(я сейчас ухожу, но на скорую руку вырезка из проекта в VC )
		//рисуем
 		BITMAPFILEHEADER* pBmpFileHeader;
 		BITMAPINFOHEADER* pBmpInfoHeader;
 		BITMAPINFO* pBmpInfo;
		pBmpFileHeader=(BITMAPFILEHEADER*)byBmpFile;
		pBmpInfoHeader=(BITMAPINFOHEADER*)(byBmpFile+sizeof(BITMAPFILEHEADER));
		pBmpInfo=(BITMAPINFO*)byBmpFile;
		BYTE* pPixels=byBmpFile+((BITMAPFILEHEADER*)byBmpFile)->bfOffBits;
		W=pBmpInfoHeader->biWidth;
		H=pBmpInfoHeader->biHeight;
		WORD BitCount=pBmpInfoHeader->biBitCount;
		tempDC.CreateCompatibleDC(pFurtherDC);
		//tempBmp.CreateCompatibleBitmap(pDC,W,H);
		pBMP->DeleteObject();
		pBMP->CreateCompatibleBitmap(pFurtherDC,W,H);
		oldbmp=tempDC.SelectObject(pBMP);
		//смотрим, сколько бит
		switch(BitCount)
		{
...
...
case 24:
{
//это я брал вроде из MSDN
	//The bitmap has a maximum of 2^24 colors, and the bmiColors member of
	//BITMAPINFO is NULL. Each 3-byte triplet in the bitmap array represents
	//the relative intensities of blue, green, and red, respectively, for a
	//pixel. The bmiColors color table is used for optimizing colors used on
	//palette-based devices, and must contain the number of entries specified
	//by the biClrUsed member of the BITMAPINFOHEADER. 
	int div=4;
	int ost=(W*3)%div;
	int delta=ost?div-ost:0;
	DWORD rgb;
	BYTE *r=pPixels+2;
	BYTE *g=pPixels+1;
	BYTE *b=pPixels+0;
	int h,w;
	for(h=H-1;h>=0;h--)
	{
		for(w=0;w<W;w++)
		{
			rgb=((*b)<<16)| ((*g)<<8)|(*r);
			tempDC.SetPixel(w,h,rgb);
			r+=3;g+=3;b+=3;
		}
		r+=delta;
		g+=delta;
		b+=delta;
	}
	result=true;
}
...
...
}
тут я копировал пикселы из BMP я рисовал на контекст tempDC
думаю это поможет разобраться 

всё, я убёг по домам