Click here to Skip to main content
15,898,725 members
Home / Discussions / C#
   

C#

 
GeneralRe: ListBox Pin
Meysam Mahfouzi29-May-04 16:55
Meysam Mahfouzi29-May-04 16:55 
GeneralRe: ListBox Pin
myNameIsRon1-Jun-04 10:38
myNameIsRon1-Jun-04 10:38 
GeneralBitmap PixelFormat GetPixel Pin
Dave12345629-May-04 14:47
Dave12345629-May-04 14:47 
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave Kreskowiak29-May-04 15:03
mveDave Kreskowiak29-May-04 15:03 
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave12345629-May-04 22:51
Dave12345629-May-04 22:51 
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave Kreskowiak30-May-04 3:06
mveDave Kreskowiak30-May-04 3:06 
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave12345630-May-04 4:45
Dave12345630-May-04 4:45 
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave1234564-Jun-04 8:13
Dave1234564-Jun-04 8:13 
I'm posting the C# solution to my original problem so that anybody who runs into the same problem can have the solution.

First, you need to import a very nice C++ DLL called BMGLib. Get it from here: http://members.cox.net/scottheiman/bmglib.htm (please see website for associated credits).

Next, create a Bitmap object (call it bmp) using UnsafeSupport.OpenBitmap. (NOTE: I am giving you the UnsafeSupport class at the end of this e-mail.)

To extract the color information from each pixel, execute the following steps. Given a pixel (int x, int y) and a Bitmap (bmp), you want a vector (float[3] rgb which contains values between 0 and 1 for each color).

float[] rgb = new float[3];
int[] xargbBppCum = UnsafeSupport.XargbBitsPerPixel(BmpOrig.PixelFormat);
for(int i=1; i<xargbBppCum.Length; i++)
xargbBppCum[i] += xargbBppCum[i-1]; //cumulative value
UnsafeSupport.GetRgb(ref rgb, xargbBppCum, x, y, bmp);

That's it. Here is the UnsafeSupport class. It encapsulates the BMGLib DLL. OH, and special thanks to Dave and the article he referenced earlier in the thread.

public unsafe class UnsafeSupport
{
/// <summary>
/// Enumeration supporting LibTiff (and ultimately Bmglib.dll).
/// </summary>
enum TiffCompressionEnum
{ NONE, CCITTRLE, CCITTFAX3, CCITTFAX4, LZW, JPEG6,
JPEG_DCT, NeXT, CCITTRLEW, MACINTOSH, THUNDERSCAN,
PIXARFILM, PIXARLOG, ZIP, KODAK, JBIG };
/// <summary>
/// Enumeration supporting LibTiff (and ultimately Bmglib.dll).
/// </summary>
enum TiffPhotometricEnum
{ MINISWHITE, MINISBLACK, RGB, PALETTE, MASK,
SEPARATED, YCBCR, CIELAB, CIE_LOGL, CIE_LOGLUV };
/// <summary>
/// Enumeration supporting LibTiff (and ultimately Bmglib.dll).
/// </summary>
enum TiffOrientationEnum { TOPLEFT, BOTTOMLEFT };
/// <summary>
/// Enumeration supporting LibTiff (and ultimately Bmglib.dll).
/// </summary>
public struct TIFFInfoStruct
{
TiffCompressionEnum compression;
TiffPhotometricEnum photometric;
TiffOrientationEnum orientation;
ushort predictor;
}
/// <summary>
/// The single import from Bmglib.dll. Supported formats and credits associated with the DLL are listed at
/// http://members.cox.net/scottheiman/bmglib.htm
/// </summary>
/// <param name="filename">string The full path of the bitmap file. The file extension determines the type of decompression.</param>
/// <param name="parameters">(void*)TIFFInfoStruct* Only returns information when a TIFF is decompressed.</param>
/// <param name="blend">int Alpha blending.</param>
/// <returns>IntPtr Handle to a GDI BITMAP object. Use Bitmap.FromHbitmap(IntPtr) to generate a Bitmap object.
/// The high-bit color information will be preserved.</returns>
[DllImport("Bmglib.dll", ExactSpelling=true, SetLastError=true)]
public static extern IntPtr CreateBitmapFromFile( [MarshalAs(UnmanagedType.LPStr)] string filename,
void* parameters, int blend );
/// <summary>
/// Because GDI+ loses 16-bit color information (only preserves 8-bit info) when opening a Bitmap object, this method
/// creates a Bitmap object by using GDI (thus skirting the GDI+ problem). After the GDI BITMAP object
/// is created, the GDI+ bitmap object is then created from the HBITMAP associated to the GDI BITMAP object. The end result
/// is that the 16-bit-color inforamtion is not lost. The endeavor is accomplished by calling the CreateBitmapFromFile method
/// in Bmglib.dll. The file extension determines the type of decompression. Supported formats and credits associated with
/// the DLL are listed here: http://members.cox.net/scottheiman/bmglib.htm
/// </summary>
public static Bitmap OpenBitmap(string filename)
{
TIFFInfoStruct tis = new TIFFInfoStruct();
IntPtr hb = CreateBitmapFromFile( filename, (void*) &tis, 0 );
return Bitmap.FromHbitmap( hb );
}
/// <summary>
/// Because GDI+ loses 16-bit color information (only preserves 8-bit info), this method searches the bitmap object and extracts
/// the appopriate 16-bit information about the RGB values for a pixel.
/// </summary>
/// <param name="RGB">float[2] Contains the output. Outputs the RGB values as values within the range of 0 to 1.</param>
/// <param name="xargbBppCum">int[5] 0, wasted bits per pixel; 1, bits per alpha pixel; 2, bits per red pixel; 3, bits per green pixel; 4, bits per blue pixel.</param>
/// <param name="x">int The x-coordinate of the pixel.</param>
/// <param name="y">int The y-coordinate of the pixel.</param>
/// <param name="bmp">Bitmap The bitmap object to extract the pixel information from.</param>
public static void GetRgb(ref float[] RGB, int[] xargbBppCum, int x, int y, Bitmap bmp)
{
RGB[0]=RGB[1]=RGB[2] = 0.0f;

BitmapData bd = bmp.LockBits( new Rectangle(x,y,1,1), ImageLockMode.ReadWrite, bmp.PixelFormat);
// bits per pixel = xargbBppCum[4]
int bypp = xargbBppCum[4]/8;
int jump = bypp*(x+bmp.Width*y);

int i;
ulong pixVal = 0ul;
ulong temp;
for(i=bypp-1; i>=0; i--)
{
pixVal = pixVal << 8;
temp = (ulong)* ( ((byte*)(void*)bd.Scan0) +i );
pixVal += (ulong)* ( ((byte*)(void*)bd.Scan0) +i );
}
int ctBit = xargbBppCum[4];
i=4;
ulong pval = 1ul;
while(ctBit >= 0 && i>1)
{
if(ctBit > xargbBppCum[i-1])
{
if(pixVal % 2ul == 1ul) RGB[i-2] += (float)pval;
pval = pval << 1;
pixVal = pixVal >> 1;
}
else
{
if(bmp.PixelFormat == PixelFormat.Format48bppRgb)
RGB[i-2] /= (float)(16384ul);
else
RGB[i-2] /= (float)(pval-1ul);
i--;
if(i>1)
{
if(pixVal % 2ul == 1ul) RGB[i-2] =1.0f;
pval = 2ul;
pixVal /= 2ul;
}
}
ctBit--;

if(bmp.PixelFormat == PixelFormat.Format48bppRgb)
{
RGB[0] *=2.0f;
RGB[1] *=2.0f;
RGB[2] *=2.0f;
}
}
bmp.UnlockBits(bd);
}

/// <summary>
/// Used for manually striding a Bitmap object (using pointers in unsafe mode). This has only been checked for
/// PixelFormat.Format24bppRgb and PixelFormat.Format48bppRgb. Use with caution for other formats.
/// ------
/// In order to use with GetRgb, you need to translate the output into a cumulative vector. For example, given a
/// bitmap object called bmp, do the following:
/// int[] xargbBppCum = XargbBitsPerPixel(bmp.PixelFormat);
// for(int i=1; i<xargbBppCum.Length; i++) xargbBppCum[i] += xargbBppCum[i-1]; //cumulative value
/// </summary>
/// <param name="pf">PixelFormat The pixel format.</param>
/// <returns>int[5] 0, wasted bits per pixel; 1, bits per alpha pixel; 2, bits per red pixel; 3, bits per green pixel;
/// 4, bits per blue pixel.</returns>
public static int[] XargbBitsPerPixel(PixelFormat pf)
{
int[] output = new int[5];
if(pf == PixelFormat.Format16bppArgb1555)
{
output[0] = 0;
output[1] = 1;
output[2] = 5;
output[3] = 5;
output[4] = 5;
}
else if(pf == PixelFormat.Format16bppRgb555)
{
output[0] = 1;
output[1] = 0;
output[2] = 5;
output[3] = 5;
output[4] = 5;
}
else if(pf == PixelFormat.Format16bppRgb565)
{
output[0] = 0;
output[1] = 0;
output[2] = 5;
output[3] = 6;
output[4] = 5;
}
else if(pf == PixelFormat.Format24bppRgb)
{
output[0] = 0;
output[1] = 0;
output[2] = 8;
output[3] = 8;
output[4] = 8;
}
else if(pf == PixelFormat.Format32bppArgb)
{
output[0] = 0;
output[1] = 8;
output[2] = 8;
output[3] = 8;
output[4] = 8;
}
else if(pf == PixelFormat.Format32bppPArgb)
{
output[0] = 0;
output[1] = 8;
output[2] = 8;
output[3] = 8;
output[4] = 8;
}
else if(pf == PixelFormat.Format32bppRgb)
{
output[0] = 8;
output[1] = 0;
output[2] = 8;
output[3] = 8;
output[4] = 8;
}
else if(pf == PixelFormat.Format48bppRgb)
{
output[0] = 16;
output[1] = 0;
output[2] = 16;
output[3] = 16;
output[4] = 16;
}
else if(pf == PixelFormat.Format64bppArgb)
{
output[0] = 0;
output[1] = 16;
output[2] = 16;
output[3] = 16;
output[4] = 16;
}
else if(pf == PixelFormat.Format64bppPArgb)
{
output[0] = 0;
output[1] = 16;
output[2] = 16;
output[3] = 16;
output[4] = 16;
}
return output;
}

}

Dave
GeneralRe: Bitmap PixelFormat GetPixel Pin
Dave1234564-Jun-04 8:22
Dave1234564-Jun-04 8:22 
GeneralRSS reader help Pin
MeterMan29-May-04 14:02
MeterMan29-May-04 14:02 
GeneralRe: RSS reader help Pin
MeterMan30-May-04 8:11
MeterMan30-May-04 8:11 
GeneralTreeView.text Pin
Ammar Ben Hadj Amor29-May-04 10:35
professionalAmmar Ben Hadj Amor29-May-04 10:35 
GeneralRe: TreeView.text Pin
Aaron Eldreth29-May-04 11:04
Aaron Eldreth29-May-04 11:04 
GeneralFrom double to Date Pin
Christer Claesson29-May-04 7:03
Christer Claesson29-May-04 7:03 
GeneralRe: From double to Date Pin
Mazdak29-May-04 10:22
Mazdak29-May-04 10:22 
GeneralRe: From double to Date Pin
Dave Kreskowiak29-May-04 14:48
mveDave Kreskowiak29-May-04 14:48 
GeneralRe: From double to Date Pin
Anonymous30-May-04 0:22
Anonymous30-May-04 0:22 
GeneralExecutable Pin
garyellis529-May-04 6:30
garyellis529-May-04 6:30 
GeneralRe: Executable Pin
Nnamdi Onyeyiri29-May-04 9:01
Nnamdi Onyeyiri29-May-04 9:01 
GeneralBinary Resource Pin
Chernobog_29-May-04 2:43
Chernobog_29-May-04 2:43 
GeneralA question about move PictureBox Pin
Member 94012528-May-04 21:39
Member 94012528-May-04 21:39 
GeneralRe: A question about move PictureBox Pin
Aaron Eldreth29-May-04 3:01
Aaron Eldreth29-May-04 3:01 
GeneralRe: A question about move PictureBox Pin
MeterMan29-May-04 14:08
MeterMan29-May-04 14:08 
GeneralRe: A question about move PictureBox Pin
Member 94012529-May-04 23:58
Member 94012529-May-04 23:58 
Generaldatareader in asp.net using c# Pin
HowRU28-May-04 19:36
HowRU28-May-04 19:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.