C# 产生空白图像的图形-有时
我正在开发一个天文学应用程序,在这个应用程序中,我必须在一个PictureBox中显示一幅科学16位FITs格式(单色)的图像。我正在与另一个DLL接口,该DLL执行一些复杂的天体测量,还提供了FITS图片的缩放、8位DIB图像(没有chioce,但要使用此DLL)。但是,它是用VB6编写的,不能与C#VS2010位图一起使用。唯一的方法,我已经能够使这项工作是通过图形。“PaintPicture”是执行转换的外部dll方法。问题在于,这种方法通常会产生空白图像,尤其是在调试模式下:C# 产生空白图像的图形-有时,c#,graphics,bitmap,vb6,handle,C#,Graphics,Bitmap,Vb6,Handle,我正在开发一个天文学应用程序,在这个应用程序中,我必须在一个PictureBox中显示一幅科学16位FITs格式(单色)的图像。我正在与另一个DLL接口,该DLL执行一些复杂的天体测量,还提供了FITS图片的缩放、8位DIB图像(没有chioce,但要使用此DLL)。但是,它是用VB6编写的,不能与C#VS2010位图一起使用。唯一的方法,我已经能够使这项工作是通过图形。“PaintPicture”是执行转换的外部dll方法。问题在于,这种方法通常会产生空白图像,尤其是在调试模式下: obs.F
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();
有人知道为什么会发生这种情况,更重要的是,知道如何解决它吗?我是在这里遗漏了什么,还是做错了什么?这与我的专业领域相去甚远,但这里有一些提示可能会有所帮助:
- 确保所有调用都来自主应用程序线程李>
- 如果没有,那么GDI有时不能正常工作
- 桌面/全屏上的所有可视内容也是如此
- 在转换之前尝试将其转储到文件
- 并在问题发生后进行检查
- 如果它也是空的,那么
- 问题可能在别处
<强> [Eddi1] VCL直接位图访问<强>(代码在BDS2006 C++中,所以必须将*BMP素材转换成VB样式)
//---------------------------------------------------------------------------
void bmp_示例()
{
图形::TBitmap*bmp;
int**pyx=NULL,xs=0,ys=0;
//[初始化位图使用]
bmp=新图形::TBitmap;//新VCL位图
bmp->HandleType=bmDIB;//独立于设备,允许直接访问
bmp->PixelFormat=pf32bit;//我使用32位匹配int/DWORD变量大小的像素
//在这里渲染/加载数据到bmp
bmp->Width=2500;//例如,将bmp调整为128x128像素
bmp->高度=2500;
//为直接访问创建所有neded
//必须在任何位图realloc/RESIGH后执行此操作
//主要思想是将指针存储到您自己的变量中
//并通过它们而不是GDI访问,以避免检查减速
如果(pyx)删除pyx;
xs=bmp->Width;//xs,ys=实际bmp大小
ys=bmp->高度;
bmp->HandleType=bmDIB;//独立于设备,允许直接访问
bmp->PixelFormat=pf32bit;//我使用32位匹配int/DWORD变量大小的像素
pyx=新整数*[ys];
对于(int y=0;yScanLine[y];
//[直接存取]
int x,y,*p;
对于(y=0;yHi Spektre-我认为这是迄今为止我所听到的最好的想法,可以解释这种不稳定的行为。我根本无法控制dll,也无法将其输出复制到文件中。基本上,我所能做的就是调用封装方法,剩下的就是一个黑匣子。我知道这不是最优的,但制造商不会做出任何更改来帮助事实上,我使用的95%都很好,但是图像显示对用户来说很重要,即使它是次要的。我唯一能控制的就是我自己。你知道我如何在主线程中强制它吗?我举个简单的例子会很有帮助。tnxi如果DLL创建自己的线程进行处理,那么答案是否定的,如果你只调用blocki从DLL调用函数(将暂停代码直到完成,然后继续),然后它们的调用必须在主线程内(在应用程序窗口的事件内,如在计时器上、在按钮上单击等…或消息过程中)。此外,您还可以测试输出是否为空,如果为空,则重复渲染,直到没有其他结果。PS这也可能是由于视觉框架(.net…只有在有帮助的情况下才尝试基本MFC内容)导致的某些不兼容我担心DLL会创建自己的线程,所以测试bmp可能是目前最好的解决方案。我确实获得了一个动态值数组(16位),并尝试将其转换为bmp,但时间太长:首先将其转换为8位(基于直方图)然后SetPixel太慢了。在6MP图像上,这需要一段时间。知道从字节数组生成单色图像的快速方法吗?我讨厌原始DLL接口,并且被锁定在其中…顺便说一句,非常感谢您的帮助和时间。Get/Set Pixels太慢(检查和转换太多)请改用扫描线(每行只检查一次)或从中创建一个线指针数组,这样就不会执行任何检查。(对于简单网格,我的软件位图渲染速度高达70fps,因此对于单次测光转换应该足够快)我尝试过,但我的图像非常大,比如6MP。相反,我使用了Marshal.Copy(pixel_array,0,data.Scan0,pixel_array.Length)。这似乎是绘制图片的最快方法。现在处理输入数组需要更长的时间。数据是16位单色格式,但我只显示其中的一部分(通常为1000到4000),这些参数取决于图像直方图。因此,我必须将字节数组渲染为这些值之间的8位。我仍在考虑最快的方法。现在它只是几个“for”循环。有什么想法吗?
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------