大神,求c#调用API的StretchDIBits函数的例子

大神,求c#调用API的StretchDIBits函数的例子

本文目录

  • 大神,求c#调用API的StretchDIBits函数的例子
  • stretchblt为什么会造成图片失真
  • DrawDibDraw和StretchDIBits和SetDIBitsToDevice哪个效率高
  • StretchDIBits显示内存中的数据问题
  • 为什么用StretchDIBits 和SetDIBitsToDevice绘图的清晰度不同
  • MFC中关于StretchDIBits的问题
  • StretchDIBits是什么
  • c#中调用函数StretchDIBits的参数问题,函数功能涉及图像处理显示

大神,求c#调用API的StretchDIBits函数的例子


enum BitmapCompressionMode : uint {
   BI_RGB = 0,
   BI_RLE8 = 1,
   BI_RLE4 = 2,
   BI_BITFIELDS = 3,
   BI_JPEG = 4,
   BI_PNG = 5
}
[StructLayout(LayoutKind.Sequential)]
public struct RGBQUAD 
{
    public byte rgbBlue; 
    public byte rgbGreen; 
    public byte rgbRed; 
    public byte rgbReserved; 
}
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
    public uint  biSize; 
    public int   biWidth; 
    public int   biHeight; 
    public ushort   biPlanes; 
    public ushort   biBitCount; 
    public BitmapCompressionMode  biCompression; 
    public uint  biSizeImage; 
    public int   biXPelsPerMeter; 
    public int   biYPelsPerMeter; 
    public uint  biClrUsed; 
    public uint  biClrImportant; 
    public void Init()
    {
        biSize = (uint)Marshal.SizeOf(this);
    }
}
[StructLayoutAttribute( LayoutKind.Sequential )]
struct BITMAPINFO {
   /// 《summary》
   /// A BITMAPINFOHEADER structure that contains information about the dimensions of color format.
   /// 《/summary》
   public BITMAPINFOHEADER bmiHeader;
   /// 《summary》
   /// An array of RGBQUAD. The elements of the array that make up the color table.
   /// 《/summary》
   [MarshalAsAttribute( UnmanagedType.ByValArray, SizeConst = 1, ArraySubType = UnmanagedType.Struct )]
   public RGBQUAD bmiColors;
}
[DllImport(“gdi32.dll“)]
static extern int StretchDIBits(IntPtr hdc, int XDest, int YDest,
   int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
   int nSrcHeight, byte  lpBits, [In] ref BITMAPINFO lpBitsInfo, uint iUsage,
   uint dwRop);

stretchblt为什么会造成图片失真


VC 下 StretchBlt 的模式及失真问题
用一个CCD的相机,采集图像,然后在对话框的图片控件中显示。
现象:原本应该是黑白相机的灰度图像,显示出来的却是花花绿绿的彩色图像。
开始的时候
怀疑是采集的数据有问题,可是查看保存下来的bmp文件,却正常的很。可以确定是显示程序的
问题。问题是,基本上是按照sdk的sample逐行抄的,唯一的一点区别就是,sdk是在一个单
文档的view中显示,我的程序是在对话框的图片控件中显示,最有可能出错的就是
StretchDIBits(pDC-》GetSafeHdc(),
rect.left,
rect.top,
rect.Width(), //显示窗口宽度
rect.Height(), //显示窗口高度
0,
0,
Width, //图像宽度
Height, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);
认真地检查了所有的参数,没有发现异常。
跑到baidu和google上疯狂地搜,又重新建立了一个对话框工程,load一个图片来显示,问题
重现,偶然看到 OnPaint():
pDC-》SetStretchBltMode(HALFTONE);
pDC-》StretchBlt(MAP_LEFT,MAP_TOP,MAP_WIDTH,MAP_HEIGHT,
&DCCompatible,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);

DrawDibDraw和StretchDIBits和SetDIBitsToDevice哪个效率高


我感觉效率由高到低应该是
SetDIBitsToDevice DrawDibDraw StretchDIBits
相信我不会错的。

StretchDIBits显示内存中的数据问题


用StretchDIBits函数vac假设你的数据存储在下面两个结构中:BITMAPINFO bmiPBYTE      pbits在视图类的OnDraw函数中添加一句:::StretchDIBits(pDC->GetSafeHdc()iko \                0 06 bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight, \                0, 0, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight,\                pbits, bmi, DIB_RGB_COLORS, SRCCOPY );即可

为什么用StretchDIBits 和SetDIBitsToDevice绘图的清晰度不同


我感觉效率由高到低应该是
SetDIBitsToDevice DrawDibDraw StretchDIBits
相信我不会错的。

MFC中关于StretchDIBits的问题


  if (x1/y1》x2/y2)
  {
   xDest=0;
   yDest=(y2-y1*(x2/x1))/2;
   DestWidth=x2;
   DestHeight=y2-yDest;
  }
  else
  {
   xDest=(x2-x1*(y2/y1))/2;
   yDest=0;
   DestWidth=x2-xDest;
   DestHeight=y2;
  }
 }

你这里的计算有问题。

第一个情况,yDest+DestHeight = y2 = wRect的高度。也就是在最下方显示了,而不是高度居中。

  if (x1*1.0/y1》x2*1.0/y2)
  {
   xDest=0;
   DestWidth=x2;
   DestHeight=y1*x2/x1;
   yDest=(y2-DestHeight)/2;
  }

这样应该就对了,else自己写一下。


StretchDIBits是什么


如果目标矩形比源矩形大小要大,那么函数对颜色数据的行和列进行拉伸,以与目标矩形匹配。如果目标矩形大小要比源矩形小,那么该函数通过使用指定的光栅操作对行列进行压缩。
  函数原型:int StretchDIBits(HDC hdc, int XDest , int YDest , int nDestWidth, int nDestHeight, int XSrc, int Ysrc, int nSrcWidth, int nSrcHeight, CONST VOID *lpBits, CONST BITMAPINFO * lpBitsInfo, UINT iUsage, DWORD dwRop);  参数:  hdc:指向目标设备环境的句柄。
  XDest:指定目标矩形左上角位置的X轴坐标,按逻辑单位来表示坐标。
  YDest:指定目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
  nDestWidth:指定目标矩形的宽度。
  nDestHeight:指定目标矩形的高度。
  XSrc:指定DIB中源矩形(左上角)的X轴坐标,坐标以像素点表示。
  YSrc:指定DIB中源矩形(左上角)的Y轴坐标,坐标以像素点表示。
  nSrcWidth:按像素点指定DIB中源矩形的宽度。
  nSrcHeight:按像素点指定DIB中源矩形的高度。
  lpBits:指向DIB位的指针,这些位的值按字节类型数组存储,有关更多的信息,参考下面的备注一节。
  lpBitsInfo:指向BITMAPINFO结构的指针,该结构包含有关DIB方面的信息。
  iUsage:表示是否提供了BITMAPINFO结构中的成员bmiColors,如果提供了,那么该bmiColors是否包含了明确的RGB值或索引。参数iUsage必须取下列值,这些值的含义如下:
  DIB_PAL_COLOR:表示该数组包含对源设备环境的逻辑调色板进行索引的16位索引值。
  DIB_RGB_COLORS:表示该颜色表包含原义的KGB值,若想了解更多的信息,请参考下面备注一节。
  返回值:如果函数执行成功,那么返回值是拷贝的扫描线数目,如果函数执行失败,那么返回值是GDI_CRROR。
  Windows NT:若想获取更多错误信息,请调用GetLastError函数。
  Windows 98、Windows NT 5.0及以后版本:如果设备驱动程序不支持传送给StretchDIBits的JPEG文件格式的图像,则该函数将失败,并返回GEI_ERROR。
  备注:自底向上的DIB的起始点为左下角,自顶向下DIB的起始点为左上角。
  如果nSrcWidth和nDestWidth参数的符号不同。或是nSrcHeight和nDesHeight参数的符号不同。那么函数StretchDIBits将创建位图的镜像。如果NsrcWidth和NdestWidth符号不同,那么函数将沿着X轴创建位图镜像。如果NsrcHeight和NdestHeight符号不同,那么函数将沿着Y轴创建位图镜像。
  如果BITMAPINFOHEADER结构中的成员biCompression为BI_JPEG,那么参数lpBits指向的是一个包含JPEG图像的缓冲区。BITMAPINFOHEADER结构中的biSizeImage成员指定了该缓冲区的大小。参数iUsage必须设为DIB_RGB_COLORS。dwRop必须设为SRCCOPY。
  如果BITMAPV4HEADER结构中的成员bV 4Compression为BI_JPEG,那么参数lpBits指向的是一个包含JPEG图像的缓冲区。BITMPV4HEADER结构中的bV4SizeImage成员指定了该缓冲区的大小。参数iUsage必须设为DIB_RGB_COLORS。参数dwRop必须设为SRCCOPY。
  如果BITMAPV5HEADER结构中的成员bV 5Compression为BI_JPEG,那么参数lpBits指向的是一个包含JPEG图像的缓冲区。BITMPV5HEADER结构中的bV5SizeImage成员指定了该缓冲区的大小。参数iUsage必须设为DIB_RGB_COLORS。dwRop必须设为SRCCOPY。
  为确保打印时可以有正确的图元文件假脱机操作。应用程序应在调用StretchDIBits函数之前调用CHECKJPEGFORMAT转义符,以确认打印机识别JPEG图像。
  ICM:执行颜色管理。如果指定的BITMAPINFO结构中的bmiHeader不包含BITMAPV4HEADER或BITMAPV5HEADER,那么当前设备环境的颜色配置(profile)被用作源颜色配置(profile)。如果没有颜色档案,那么就使用RGB。如果指定的BITMAPINFO结构中的成员bmiHeader包含了BITMAPV4HEADER或BITMAPV5HEADER,那么将把位图标头中指定的颜色配置(profile)用作源颜色配置。

c#中调用函数StretchDIBits的参数问题,函数功能涉及图像处理显示


Graphics g
StretchDIBits(g.GetHdc(), 0, 0, 512, 512, 0, 0, 512, 512, pt, bm, DIB_RGB_COLORS, SRCCOPY);
别人写的
public void DrawImage(byte pixels, Graphics g)
{
// Create a BITMAPINFO object representing the image to be drawn
// Image is 512 x 512, 8bpp
BITMAPINFO bmi = new BITMAPINFO();
bmi.biWidth = 512;
bmi.biHeight = 512;
bmi.biPlanes = 1;
bmi.biBitCount = 8;
bmi.biSizeImage = pixels.Length;
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BITMAPINFO)));
[color=#FF0000] Marshal.Copy(pixels, 0, pt, Marshal.SizeOf(typeof(BITMAPINFO)));
IntPtr bm = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BITMAPINFO)));[/color] // Draw the image using the graphics object
StretchDIBits(g.GetHdc(), 0, 0, 512, 512, 0, 0, 512, 512, pt, bm, DIB_RGB_COLORS, SRCCOPY);
}

推荐阅读