Chris K
Chris K

Reputation: 21

Graphics Producing a Blank Image - Sometimes

I am working on an astronomy application, where I have to display an image from a scientific 16 bit FITs format (monochrome) in a PictureBox. I am interfacing with another DLL that performs some complex astrometry, and also provides a scaled, 8 bit DIB image of the FITS picture (no chioce but to use this dll). It is however written with VB6 in mind, and it will not work with a C# VS2010 Bitmap. The only way I have been able to make this work is to go thru Graphics. The “PaintPicture” is an external dll method that does the conversion. The problem is that this approach often produces a blank image, particularly when in debugging mode:

obs.FITSbmp = new Bitmap(obs.p.Columns, obs.p.Rows);
pictureBoxFITS.BackgroundImage = obs.FITSbmp;
obs.g = Graphics.FromImage(obs.FITSbmp); 
//Have to go thru graphics as PP targets VB6
obs.pic.PaintPicture((int)obs.g.GetHdc());
obs.g.ReleaseHdc();

Does anyone have an idea why this is happening, and more importantly, how to fix it? Am I missing something here, or am I doing something wrong?

Upvotes: 2

Views: 371

Answers (1)

Spektre
Spektre

Reputation: 51845

This is far far away from my field of expertise but here are some hints that may help:

  1. it looks like you (and or the DLL) use GDI.

    • Make sure that all calls are from main application thread.
    • if not then GDI don't work properly sometimes ...
    • the same goes for all visual stuff on desktop/full-screen
  2. are you sure that the unconverted bitmap is rendered properly?

    • try to dump it to file before conversion
    • and check it after your problem occur
    • if it is also blank then
    • the problem can be elsewhere

[Edit1] VCL direct bitmap access (code in BDS2006 C++ so you must convert *bmp stuff to VB style)

//---------------------------------------------------------------------------
void bmp_example()
    {
    Graphics::TBitmap *bmp;
    int **pyx=NULL,xs=0,ys=0;

    // [init bitmap use]
    bmp=new Graphics::TBitmap;  // new VCL bitmap
    bmp->HandleType=bmDIB;      // is Device independent to allow direct access
    bmp->PixelFormat=pf32bit;   // i use 32 bit to match pixel with int/DWORD variable size

    // here render/load data into bmp
    bmp->Width=2500;             // for example resize bmp to 128x128 pixels
    bmp->Height=2500;

    // create all neded for direct  access
    // must do this after any bitmap realloc/resize
    // main idea is to store pointers into your own variables
    // and access throu them instead of GDI to avoid checking slow-downs
    if (pyx) delete pyx;
    xs=bmp->Width;              // xs,ys = actual bmp size
    ys=bmp->Height;
    bmp->HandleType=bmDIB;      // is Device independent to allow direct access
    bmp->PixelFormat=pf32bit;   // i use 32 bit to match pixel with int/DWORD variable size
    pyx=new int*[ys];
    for (int y=0;y<ys;y++)      // copy line pointers to pyx
     pyx[y]=(int*)bmp->ScanLine[y];

    // [direct access]
    int x,y,*p;
    for (y=0;y<ys;y++)          // fill whole bmp
     for (x=0;x<xs;x++)
        {                       // this will fill bmp with grayscale diagonal patern
        pyx[y][x]=((x+y)&255)*0x00010101;
        }
    for (x=0;x<xs;x++)          // does not mater which loop is first
     for (y=0;y<ys;y++)
        {                       // this will fill bmp with grayscale diagonal patern
        pyx[y][x]=((x+y)&255)*0x00010101;
        }
    for (y=0;y<ys;y++)          // this is bit faster (but not by much and limitaccess to lines so y loop must be first)
        {
        p=pyx[y];               // acces just line to avoid 2D addresing
        for (x=0;x<xs;x++)
            {                   // this will clear bmp with white color
            p[x]=0x00FFFFFF;
            }
        }

    // [exit btmap use]
    if (bmp) delete bmp; bmp=NULL;
    if (pyx) delete pyx; pyx=NULL;
    }
//---------------------------------------------------------------------------
  • this example 3 times fill 2500x2500 pixel 32bit bitmap ~ 6MP
  • on my machine (Win7 x64 AMD 3.2GHz) is runtime about 118ms (compiled as 32bit app)
  • avoid any use of bitmap use pyx,xs,ys instead
  • if this not helps then you can probably have some performance problem in your code
  • but without posting it here i just guess
  • the best way is to measure the time of your processing steps
  • and then you will see where is the slowdown
  • I guess some horribly coded loop in histogram
  • do not forget to draw the bitmap onto window before deleting it
  • also you can alloc/delete it on app init/exit and have it in memory the whole time
  • any resize,format change (even inside that DLL functions) can reallocate bitmap memory so pyx must be updated after ...

[Edit2] I have another idea what might be wrong.

I see that you are accessing piantbox bitmap from your DLL

  • paintbox have tendency to update image sometimes when it should not (at least from VCL)
  • this can blank your image (I had problems with it before also)
  • usually well placed update call sort things out
  • or try to create separate bitmap and render it from DLL and then draw it onto paintbox.
  • if it is blank and the bitmap not then just draw it again onto paintbox

Upvotes: 1

Related Questions