标签: bitblt

如何提高GDI的DrawImage(Unscaled)的性能?

在我的用户控件的绘图处理程序中,我遍历一组预定义的Bitmap对象,并将它们绘制到客户区:

C#版本:

private void Control_Paint(object sender, PaintEventArgs e) {
    Graphics g = e.Graphics;
    foreach (BitmapObj bmpObj in _bitmapObjCollection) {
        g.DrawImageUnscaled(bmpObj.Bitmap, bmpObj.Location);
    }
}
Run Code Online (Sandbox Code Playgroud)

VB.NET版本:

Private Sub Control_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
    Dim g As Graphics = e.Graphics

    For Each bmpObj As BitmapObj In _bitmapObjCollection
        g.DrawImageUnscaled(bmpObj.Bitmap, bmpObj.Location)
    Next
End Sub
Run Code Online (Sandbox Code Playgroud)

代码工作正常但是当十几个对象添加到集合时开始陷入困境.我的问题是:有没有办法加快速度?是否可以使用Win32 bitblt函数替换DrawImageUnscaled?如果是这样怎么样?

谢谢!

注意:到目前为止,谷歌搜索BitBlt的使用仅产生了我的屏幕截图样本......

c# vb.net performance drawimage bitblt

5
推荐指数
1
解决办法
3891
查看次数

Qt4中的BitBlt?

在Qt4的特定位置将一个QImage复制到另一个QImage的推荐方法是什么?

在Qt4中删除了QImage :: bitblt.

QImage现在是否需要转换为PixMap并返回?

qt qt4 bitblt

5
推荐指数
1
解决办法
3477
查看次数

是否有可能直接从GDI +位图BitBlt?

是否可以使用BitBlt直接从GDI +位图复制而不使用GetHBitmap?

GetHBitmap很慢,因为它创建了整个图像的新副本,除了比BitBlt副本慢,并且必须处理给定的HBITMAP.图像很大.

有没有办法指向BitBlt使用原始GDI +图像的像素数据?

编辑: 我可以获得指向GDI +位图像素数据在内存中的位置的指针.我可以创建一个指向GDI +位图像素数据的HBITMAP以避免额外的复制,并从中创建BitBlt吗?

winapi gdi+ gdi bitblt

5
推荐指数
1
解决办法
4836
查看次数

将图形内容复制到位图

我尝试将图形对象的内容复制到位图.我正在使用此代码

public static class GraphicsBitmapConverter
{
    [DllImport("gdi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    public static Bitmap GraphicsToBitmap(Graphics g, Rectangle bounds)
    {
        Bitmap bmp = new Bitmap(bounds.Width, bounds.Height);

        using (Graphics bmpGrf = Graphics.FromImage(bmp))
        {
            IntPtr hdc1 = g.GetHdc();
            IntPtr hdc2 = bmpGrf.GetHdc();

            BitBlt(hdc2, 0, 0, bmp.Width, bmp.Height, hdc1, 0, 0, TernaryRasterOperations.SRCCOPY);

            g.ReleaseHdc(hdc1);
            bmpGrf.ReleaseHdc(hdc2);
        }

        return bmp;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我像这样使用这种方法

Graphics …
Run Code Online (Sandbox Code Playgroud)

c# graphics gdi+ bitmap bitblt

5
推荐指数
1
解决办法
7401
查看次数

如何使用aero加速BitBlt捕获屏幕?

我使用以下代码来捕获具有GDI函数的屏幕:

// Prologue:

int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);

HDC hScreenDC = GetDC(0);
HDC hCaptureDC = CreateCompatibleDC(hScreenDC);
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hScreenDC, iScreenWidth, iScreenHeight);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCaptureDC, hCaptureBitmap);

// Capture:

BitBlt(hCaptureDC, 0, 0, iScreenWidth, iScreenHeight, hScreenDC, 0, 0, SRCCOPY);

// --- ... --- //

// Epilogue:

SelectObject(hCaptureDC, hOldBitmap);
DeleteObject(hCaptureBitmap);
DeleteDC(hCaptureDC);
ReleaseDC(0, hScreenDC);
Run Code Online (Sandbox Code Playgroud)

问题是:BitBlt函数是WAY当Aero是打开慢-它需要近50毫秒(这对我来说是不可接受的,因为我需要捕捉多次排在第二).

BitBlt直接从视频硬件获取像素数据.但是在我的测试机器(即Radeon 5470和Radeon 4850)中显卡非常好,所以我不明白什么是错的.我知道这些卡(任何现代卡)在2D中并不像3D那样好,但是我认为简单的blit操作不应该花费50ms.

那么,请你建议做什么?在我的情况下,任何一种"hackish"解决方案(只要它稳定工作)都可以.

目标系统是Win7 x64,32位代码.

提前致谢!

gdi screen-capture bitblt visual-c++

5
推荐指数
1
解决办法
3895
查看次数

Qt:Qt5 Windows中BitBlt的替代品

我目前正在从Qt3到Qt5 移植一个开源解决方案(Albatross ATM解决方案http://www.albatross.aero/).信天翁是一个空中交通观众,需要非常好的表现.我可以管理各种问题,但不能显示部分.

显示架构依赖于一个bitblt命令,该命令首先将一个像素图复制到另一个像素图中,最后将像素图复制到屏幕上.

这是Qt3显示代码(工作和性能):

void CAsdView::paintEvent ( QPaintEvent * Event)
{
    QRect   rcBounds=Event->rect();

    QPainter tmp;

    for (int lay=0;lay<(int)m_RectTable.size();lay++) //For each drawing layer (there are 3) 
    {

        if (!m_RectTable[lay].isEmpty())
        {
            if (lay!=0)
                bitBlt(m_BitmapTable[lay],m_RectTable[lay].left(),m_RectTable[lay].top(),m_BitmapTable[lay-1],m_RectTable[lay].left(),m_RectTable[lay].top(),m_RectTable[lay].width(),m_RectTable[lay].height(),CopyROP); //m_BitmapTable is a QVector< QPixmap* >, m_RectTable is a QVector<QRect>

            tmp.begin(m_BitmapTable[lay]);

            if (lay==0)
                tmp.fillRect(m_RectTable[lay], *m_pBrush);

            OnDraw(&tmp,lay);
            tmp.end();
            m_RectTable[lay].setRect(0,0,-1,-1);
        }
    }
    bitBlt(this, rcBounds.left(), rcBounds.top(),m_BitmapTable[m_LayerNb-1],rcBounds.left(), rcBounds.top(),rcBounds.width(), rcBounds.height(), CopyROP);  
}
Run Code Online (Sandbox Code Playgroud)

我试过替换bitblt,drawPixmap但性能非常差,因为我必须经常显示屏幕.

这是新的Qt5代码:

void CAsdView::paintEvent ( QPaintEvent * Event)
{
    QRect   rcBounds=Event->rect(); …
Run Code Online (Sandbox Code Playgroud)

c++ qt porting bitblt qt5

5
推荐指数
1
解决办法
1727
查看次数

BitBlt没有在硬件加速模式下捕获窗口

我正在使用GDI32.dll捕获窗口快照,虽然我遇到了硬件加速Windows的问题,我想知道是否有办法规避.

我在这里找到了这个惊人的代码:

public static Image CaptureWindow(IntPtr handle)
{

    IntPtr hdcSrc = User32.GetWindowDC(handle);

    Rect windowRect = new Rect();
    User32.GetWindowRect(handle, ref windowRect);

    int width = windowRect.Right - windowRect.Left;
    int height = windowRect.Bottom - windowRect.Top;

    IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
    IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);

    IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
    Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
    Gdi32.SelectObject(hdcDest, hOld);
    Gdi32.DeleteDC(hdcDest);
    User32.ReleaseDC(handle, hdcSrc);

    Image image = Image.FromHbitmap(hBitmap);
    Gdi32.DeleteObject(hBitmap);

    return image;
}
Run Code Online (Sandbox Code Playgroud)

适用于所有窗户,除了我的镀铬窗户.在chrome中禁用硬件加速修复了这个问题虽然我不想这样做.

任何人对此问题有任何建议/解决方案吗?

感谢您的帮助,

- 保罗

c# gdi bitblt

5
推荐指数
0
解决办法
581
查看次数

BitBlt代码不起作用

我正在尝试使用此代码Bitmap直接绘制到PictureBox:

Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
Graphics grDest = Graphics.FromHwnd(pictureBox1.Handle);
Graphics grSrc = Graphics.FromImage(bmp);
IntPtr hdcDest = grDest.GetHdc();
IntPtr hdcSrc = grSrc.GetHdc();
BitBlt(hdcDest, 0, 0, pictureBox1.Width, pictureBox1.Height,
    hdcSrc, 0, 0, (uint)TernaryRasterOperations.SRCCOPY); // 0x00CC0020
grDest.ReleaseHdc(hdcDest);
grSrc.ReleaseHdc(hdcSrc);
Run Code Online (Sandbox Code Playgroud)

但是不是渲染Bitmap它的内容,而是绘制一个近乎黑色的固体块.我很确定问题出在源hDC上,因为如果我在上面的代码中将SRCCOPY更改为WHITENESS,它会按预期绘制一个纯白色块.

注意:这个下一个片段工作正常,所以位图本身没有任何问题:

Bitmap bmp = (Bitmap)Bitmap.FromFile(@"C:\Users\Ken\Desktop\Load2.bmp");
pictureBox1.Image = bmp;
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke gdi+ bitblt

4
推荐指数
1
解决办法
8520
查看次数

C# Bitblit 从 Bitmap 到控件(Compact Framework)

我曾经使用 BitBlt 将屏幕截图保存到图像文件(.Net Compact Framework V3.5、Windows Mobile 2003 及更高版本)。工作得很好。现在我想在表单上绘制位图。我可以使用this.CreateGraphics().DrawImage(mybitmap, 0, 0),但我想知道它是否可以像以前一样与 BitBlt 一起使用并且只是交换参数。所以我写道:

[DllImport("coredll.dll")]
public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
Run Code Online (Sandbox Code Playgroud)

(再往下走:)

IntPtr hb = mybitmap.GetHbitmap();
BitBlt(this.Handle, 0, 0, mybitmap.Width, mybitmap.Height, hb, 0, 0, 0x00CC0020);
Run Code Online (Sandbox Code Playgroud)

但形式保持纯白色。这是为什么?我犯的错误在哪里?谢谢你的意见。干杯,大卫

c# graphics windows-mobile bitblt

3
推荐指数
1
解决办法
8682
查看次数

Win32 C++ BitBlt 光栅方法和透明度

我最近问了一个关于这个的问题,并理解了答案,但无法将其翻译成代码。经过一天的乱搞东西,并修复泄漏。不过,我一生都无法弄清楚这一点。

这有点不同,我需要做的就是在地图位图下获取背景位图。我拥有的

HDC hdc = GetDC(hWnd);
HDC hdcMem = CreateCompatibleDC(hdc);
HDC hdcMem2 = CreateCompatibleDC(hdc);
ReleaseDC(hWnd, hdc);

HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, bitmap.hbmBackground);
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem, 0, 0, SRCCOPY);       

HBITMAP hbmOld2 = (HBITMAP)SelectObject(hdcMem2, bitmap.hbmMap);
BitBlt(buffer.getBufferDC(), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, hdcMem2, 0, 0, SRCPAINT); 

SelectObject(hdcMem2, hbmOld2);
Run Code Online (Sandbox Code Playgroud)

我的问题是结合...创建内存 dcs 以保留光栅操作的结果。我根本无法解决这个问题,任何帮助都会很棒。

谢谢。

c++ winapi transparency bitblt

3
推荐指数
1
解决办法
4684
查看次数

MFC BitBlt和SetDIBits与SetBitmapBits

我有一个位图存储为BGRA字节数组.这是我用来绘制位图的代码:

CDC *dispDC = new CDC();
dispDC->CreateCompatibleDC(pDC);
CBitmap *dispBMP = new CBitmap();
dispBMP->CreateCompatibleBitmap(pDC, sourceImage->GetWidth(), sourceImage->GetHeight());
dispDC->SelectObject(this->dispBMP);
Run Code Online (Sandbox Code Playgroud)

实际复制translatedImage数组中的像素时会发生以下情况:

dispBMP->SetBitmapBits(sourceImage->GetArea() * 4, translatedImage);
Run Code Online (Sandbox Code Playgroud)

经过一些处理之后,我打电话pDC->StretchBltdispDC作为源CDC.这在本地登录时工作正常,因为显示也设置为32bpp.

一旦我使用远程桌面登录,显示屏将变为16bpp并且图像被破坏.罪魁祸首是SetBitmapBits; 即为了它的工作,我必须正确填写translatedImage我想要显示的16bpp版本.我没有自己这样做,而是搜索了文档,发现SetDIBits它听起来像我想要的那样:

SetDIBits函数使用在指定DIB中找到的颜色数据设置兼容位图(DDB)中的像素.

在我的例子中,DIB是32bpp RGBA数组,而DDB是dispBMP我创建的CreateCompatibleBitmap.

所以不是我的号召SetBitmapBits,这就是我所做的:

BITMAPINFO info;
ZeroMemory(&info, sizeof(BITMAPINFO));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = sourceImage->GetArea()*4;
info.bmiHeader.biWidth = sourceImage->GetWidth();
info.bmiHeader.biHeight = sourceImage->GetHeight();
info.bmiHeader.biClrUsed = 0;

int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
                  0, …
Run Code Online (Sandbox Code Playgroud)

c++ mfc bitmap dib bitblt

3
推荐指数
1
解决办法
3701
查看次数

为什么Bitblt无法工作

>   case WM_PAINT:          
                      {
>               hdc = BeginPaint(hWnd, &ps);
>               // TODO: Add any drawing code here...
>               RECT rt;
>               GetClientRect(hWnd, &rt);
>               HDC myHdc = CreateCompatibleDC(hdc);
>               
>               DrawText(myHdc, szHello, strlen(szHello), &rt, DT_CENTER);
>               BitBlt(hdc,0,0,rt.right-rt.left,rt.bottom-rt.top,myHdc,0,0,SRCCOPY);
>               
>               EndPaint(hWnd, &ps);            
                        }
> 
>           break;
Run Code Online (Sandbox Code Playgroud)

为什么文字无法在窗口显示?

windows gdi bitblt

1
推荐指数
1
解决办法
1584
查看次数

BitBlt内存泄漏

我正在使用BitBlt在我的按钮上显示位图.对于大多数情况,它很好,但有一个内存泄漏导致程序在一段时间后崩溃.我做错了什么?

int Springboard::DrawBasicButtons(DRAWITEMSTRUCT* pdis, HINSTANCE hInstance){
    RECT rect;
    static HBITMAP hCurrIcon, hIconoff, hIconon;
    rect = pdis->rcItem;

    HFONT font = CreateFont(13, 0, 0, 0, 300, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Arial");
    TCHAR Txtstr[MAX_PATH];
    BOOL isText = FALSE;
    int textsize;

    if (IDC_HOLD == pdis->CtlID) {
        hIconoff = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(BASIC_HOLDOFF));
        hIconon = (HBITMAP) LoadBitmap(hInstance, MAKEINTRESOURCE(BASIC_HOLDON));
        _tcscpy( Txtstr, _T("Hold      "));
        isText = TRUE;
        if (pdis->itemState & ODS_SELECTED) hCurrIcon = hIconon;
        else hCurrIcon = hIconoff;
    }

    HDC hdc = CreateCompatibleDC(pdis->hDC);
    SelectObject(hdc, …
Run Code Online (Sandbox Code Playgroud)

c++ winapi memory-leaks bitmap bitblt

0
推荐指数
1
解决办法
541
查看次数