Results 1 to 7 of 7

Thread: SetDIBitsToDevice , GetDIBits (Blurry text)

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    SetDIBitsToDevice , GetDIBits (Blurry text)

    Hi all,

    The following simple test code takes a snapshot of the desktop screen, produces a BMP image in memory , retrieves all the pixels in the BMP ,replace the white pixels with green pixels and finally copy the altered BMP back to the screen using the SetDIBitsToDevice GDI API.

    Problem:

    Although the code works, the resulting text is blurred/reddish.

    Question:
    Is there a way of getting a smooth text ?


    I have also used the TransparentBlt API in another code but I i get the same text-blurring problem.

    Code:
    Option Explicit
    
    Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
    End Type
    
    Type RGBQUAD
        rgbBlue As Byte
        rgbGreen As Byte
        rgbRed As Byte
        rgbReserved As Byte
    End Type
    
    Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors As RGBQUAD
    End Type
    
    Declare   Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Declare   Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Declare   Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Declare   Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Declare   Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Declare   Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Declare   Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Declare   Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
    Declare   Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    Declare   Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
    Declare   Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    
    
    Const DIB_RGB_COLORS = 0
    Const SM_CXSCREEN = 0
    Const SM_CYSCREEN = 1
    Const SRCCOPY = &HCC0020
    Const CAPTUREBLT = &H40000000
    Const BI_RGB = 0&
    
    
    Function getScreenBMP(hdcSrc As Long) As Long
    
        Dim nScreenWidth As Long, nScreenHeight As Long
        Dim hCaptureDC  As Long, hBitmap As Long, hOld As Long
        
        nScreenWidth = GetSystemMetrics(SM_CXSCREEN)
        nScreenHeight = GetSystemMetrics(SM_CYSCREEN)
        ' // Create compatible DC, create a compatible bitmap and copy the screen using BitBlt()
        hCaptureDC = CreateCompatibleDC(hdcSrc)
        hBitmap = CreateCompatibleBitmap(hdcSrc, nScreenWidth, nScreenHeight)
        hOld = SelectObject(hCaptureDC, hBitmap)
        'Make a copy of the screen
        'TODO: take subset
        Call BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hdcSrc, 0, 0, SRCCOPY Or CAPTUREBLT)
        Call SelectObject(hCaptureDC, hOld) ' // always select the previously selected object once done
        Call DeleteDC(hCaptureDC)
        getScreenBMP = hBitmap
    End Function
    
    
    
    Sub testMain()
    
        Dim myBMInfo As BITMAPINFO
        Dim lpPixels() As RGBQUAD
        Dim hdc As Long, hBitmap As Long
        
        hdc = GetDC(0)
        hBitmap = getScreenBMP(hdc)
        
        myBMInfo.bmiHeader.biSize = LenB(myBMInfo.bmiHeader)
        ' // Get the BITMAPINFO structure from the bitmap
        Call GetDIBits(hdc, hBitmap, 0, 0, vbNull, myBMInfo, DIB_RGB_COLORS)
        ' // create the bitmap buffer
        ' ReDim lpPixels(myBMInfo.bmiHeader.biSizeImage / 4)
        ReDim lpPixels(myBMInfo.bmiHeader.biWidth, myBMInfo.bmiHeader.biHeight)
        
        ' // Better do this here - the original bitmap might have BI_BITFILEDS, which makes it
        ' // necessary to read the color table - you might not want this.
        myBMInfo.bmiHeader.biCompression = BI_RGB
        
        ' // get the actual bitmap buffer
       Call GetDIBits(hdc, hBitmap, 0, myBMInfo.bmiHeader.biHeight, lpPixels(1, 1), myBMInfo, DIB_RGB_COLORS)
        
        Dim x As Long, y As Long
    
        '// replace white pixels with green pixels
          For x = 0 To myBMInfo.bmiHeader.biWidth
              For y = 0 To myBMInfo.bmiHeader.biHeight
              If lpPixels(x, y).rgbGreen = 255 And lpPixels(x, y).rgbBlue = 255 And lpPixels(x, y).rgbRed = 255 Then
                    lpPixels(x, y).rgbGreen = 255: lpPixels(x, y).rgbBlue = 0: lpPixels(x, y).rgbRed = 0
              End If
              Next y
          Next x
    
        SetDIBitsToDevice hdc, 0, 0, myBMInfo.bmiHeader.biWidth, myBMInfo.bmiHeader.biHeight, 0, 0, 0, myBMInfo.bmiHeader.biHeight, lpPixels(1, 1), myBMInfo, DIB_RGB_COLORS
    
        Call DeleteObject(hBitmap)
        Call ReleaseDC(vbNull, hdc)
    
    End Sub


    This is what I get : (Notice the blurred text)




    Also, Does the GDI+ provide a better alternative ?

    Regards.

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    I would think that the text is blended into the background. The area around the text edges are not crisp so you will have black text with probably a grayish edge where the black was blended into the original white background. When you replace white with green, those blended pixels are not pure white (RGB 255,255,255). That is likely the reason for the blurriness.

    A better alternative? Not really. If you try to change a range of colors from White to near-white, you may get better results around the text, but then other near-white colors may be converted to green that you didn't want to be green

    P.S. vbNull is not the value zero: MsgBox vbNull
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    Edited

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    @LaVolpe

    So I guess there is no way of remeding this text blurring issue ?

    Also, I was wondering if there is a way of replacing the targeted color in one bulk instead of looping through each pixel to gain speed ? Iterating the pixels in the BMP one by one is very slow.

    And how about the GDI+ library ?

    Thanks.


    Late edit:

    I could replace the color without looping via the use of the TransparentBlt API function but I was wondering if there is another way .
    Last edited by JAAFAR; Mar 11th, 2019 at 08:38 PM.

  5. #5
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    Isn't this just ClearType or other antialiasing of text? You could turn all of that off, but who wants to live with the result?

    Or maybe I'm just missing something too subtle for me to grasp right now. Allergy meds, bleh.

  6. #6
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,733

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    I agree with dilettante.
    Text on screen is anti aliased (whether by ClearType or something else), so making a screenshot and replace white with green will give very odd results.

  7. #7
    Fanatic Member
    Join Date
    Sep 2010
    Location
    Italy
    Posts
    731

    Re: SetDIBitsToDevice , GetDIBits (Blurry text)

    You could try :
    If. SourceR = sourceG and sourceR=sourceB then
    TargetR=0:targerG=sourceG:targetB=0.. Maybe too much greenish result

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width