Grab desktop wallpaper to image?

Just starting out? Need help? Post your questions and find answers here.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Grab desktop wallpaper to image?

Post by Dude »

How can I grab the desktop wallpaper as an image, without the desktop icons on it, and without opening a window? I can do it if I toggle the desktop icons before and after, but that's ugly. I just want to copy the wallpaper image direct to my own created image. And no, I can't get the path of the wallpaper file because it may be a JPG (on Windows 7). Thanks!
Last edited by Dude on Sun May 28, 2017 12:50 pm, edited 2 times in total.
kvitaliy
Enthusiast
Enthusiast
Posts: 162
Joined: Mon May 10, 2010 4:02 pm

Re: Grab desktop wallpaper to image?

Post by kvitaliy »

The source code is taken from this forum:

Code: Select all

ExamineDesktops()
SCREENX = DesktopWidth(0)
SCREENY = DesktopHeight(0)
UseJPEGImageEncoder()
OpenWindow(0,0,0,SCREENX,SCREENY,"Wallpaper Copy")
CreateImage(0,SCREENX,SCREENY,#PB_Image_DisplayFormat)
hWin = GetDC_(WindowID(0))
PaintDesktop_(hWin)
hImage = StartDrawing(ImageOutput(0))
BitBlt_(hImage,0,0,SCREENX,SCREENY,hWin,0,0,#SRCCOPY)
StopDrawing()
SaveImage(0,"c:\Wallpaper.jpg",#PB_ImagePlugin_JPEG)
ReleaseDC_(WindowID(0),hWin)
InvalidateRect_(WindowID(0),0,1)
kvitaliy
Enthusiast
Enthusiast
Posts: 162
Joined: Mon May 10, 2010 4:02 pm

Re: Grab desktop wallpaper to image?

Post by kvitaliy »

Another full path to the wallpaper:

Code: Select all

;get wallpaper

CoInitialize_(0)

wbuf=AllocateMemory(1000,0) ;wide char
mbuf=AllocateMemory(1000,0) ;multy byte

CoCreateInstance_(?CLSID_ActiveDesktop,0,1,?IID_IActiveDesktop,@pobj.IActiveDesktop)

pobj\GetWallpaper(wbuf,1000,0)

pobj\release()

WideCharToMultiByte_(#CP_ACP,0,wbuf,-1,mbuf,1000,#Null,#Null)

P$=PeekS(mbuf,1000,#PB_Ascii)
MessageRequester("Wallpapers here: ",P$)

CoUninitialize_()
FreeMemory(wbuf)
FreeMemory(mbuf)
End

;CLSID_ActiveDesktop="{75048700-EF1F-11D0-9888-006097DEACF9}"
;IID_IActiveDesktop="{F490EB00-1240-11D1-9888006097DEACF9}"

DataSection
CLSID_ActiveDesktop:
Data.l $75048700
Data.w $EF1F,$11D0
Data.b $98,$88,$00,$60,$97,$DE,$AC,$F9

IID_IActiveDesktop:
Data.l $F490EB00
Data.w $1240,$11D1
Data.b $98,$88,$00,$60,$97,$DE,$AC,$F9
EndDataSection

Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Grab desktop wallpaper to image?

Post by Dude »

Thanks, but both responses do NOT do what I asked. :(

I don't want to open a window, because the wallpaper needs to be copied silently without interrupting the user with a window popping up and taking the focus from their current window.

And the path to the wallpaper is no good if the wallpaper is a JPG image, which it can be on Windows 7 (mine currently is), or if the image file gets deleted while the wallpaper is shown.

So, are there any other ways to just copy the wallpaper to an image silently?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Grab desktop wallpaper to image?

Post by netmaestro »

May I ask why a JPG image is no good? This is working fine here with a jpg on win7:

Code: Select all

wall$ = Space(#MAX_PATH)
SystemParametersInfo_(#SPI_GETDESKWALLPAPER, #MAX_PATH, @wall$, 0)
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseTIFFImageDecoder()
LoadImage(0, wall$)
ShowLibraryViewer("image", 0)
CallDebugger
You'll have to decide how you want to activate the grabber, hotkey or whatever you have in mind. Maybe a message-only window (which is invisible and has no desktop footprint at all)
BERESHEIT
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Grab desktop wallpaper to image?

Post by Bisonte »

If you want to load any picture that windows can show to an image : The function LoadImageEX() from Stefan at the german forum helps...

And to get the full filename from the wallpaper, you only need one API functions.

Here an example :

Code: Select all

;: ============================================================================
;: LoadImageEx() 
;: Author : Stefan
;: Forum  : http://www.purebasic.fr/german/viewtopic.php?t=12155
;: 
;: Load any picture without PB-ImagePlugins (jpg,png,bmp,gif, etc.)
;: ----------------------------------------------------------------------------

; #DDBLT_WAIT           = $1000000
; #DXLOCKF_READ         = 0
; #CLSCTX_INPROC_SERVER = 1
; In PB5.60 integrated

Interface nIDXSurfaceFactory
  QueryInterface(a, b)
  AddRef()
  Release()
  CreateSurface(a, b, c, d, e, f, g, h)
  CreateFromDDSurface(a, b, c, d, e, f)
  LoadImage(a.p-bstr, b, c, d, e, f)
  LoadImageFromStream(a, b, c, d, e, f)
  CopySurfaceToNewFormat(a, b, c, d, e)
  CreateD3DRMTexture(a, b, c, d, e)
  BitBlt(a, b, c, d, e)
EndInterface
DataSection
  CLSID_DXTransformFactory:
  Data.l $D1FE6762
  Data.w $FC48,$11D0
  Data.b $88,$3A,$3C,$8B,$00,$C1,$00,$00
 
  IID_IDXTransformFactory:
  Data.l $6A950B2B
  Data.w $A971,$11D1
  Data.b $81,$C8,$00,$00,$F8,$75,$57,$DB
 
  IID_IDXSurfaceFactory:
  Data.l $144946F5
  Data.w $C4D4,$11D1
  Data.b $81,$D1,$00,$00,$F8,$75,$57,$DB
 
  IID_IDXSurface:
  Data.l $B39FD73F
  Data.w $E139,$11D1
  Data.b $90,$65,$00,$C0,$4F,$D9,$18,$9D
EndDataSection
Procedure.i LoadImageEx(Image, FileName.s, Flags=32)
  
  Protected result=CoInitialize_(0)
  Protected dxtf.IDXTransformFactory, dxsf.nIDXSurfaceFactory
  Protected surf.IDXSurface, lock.IDXDCLock, re.rect
  Protected DC.i, DestDC.i, Success.i
  
  If result=#S_FALSE Or result=#S_OK
   
    CoCreateInstance_(?CLSID_DXTransformFactory,0,#CLSCTX_INPROC_SERVER,?IID_IDXTransformFactory,@dxtf.IDXTransformFactory)
   
    If dxtf
      dxtf\QueryService(?IID_IDXSurfaceFactory,?IID_IDXSurfaceFactory,@dxsf.nIDXSurfaceFactory)
      If dxsf
        dxsf\LoadImage(FileName,0,0,0,?IID_IDXSurface,@surf.IDXSurface)
        If surf
         
          surf\LockSurfaceDC(0,#INFINITE,#DXLOCKF_READ,@lock.IDXDCLock)
          If lock
            DC=lock\GetDC()
           
            If DC
              GetClipBox_(DC,re.rect)
             
              If Image=#PB_Any
                result=CreateImage(#PB_Any,re\right,re\bottom,Flags)
                Image=result
              Else
                result=CreateImage(Image,re\right,re\bottom,Flags)
              EndIf
             
              If result
               
                DestDC=StartDrawing(ImageOutput(Image)) 
                If DestDC
                  Success=BitBlt_(DestDC,0,0,re\right,re\bottom,DC,0,0,#SRCCOPY)
                  StopDrawing()         
                EndIf
               
                If Success=#False:FreeImage(Image):EndIf
              EndIf
            EndIf
           
            Lock\Release()     
          EndIf
         
          surf\Release()
        EndIf
       
        dxsf\Release()
      EndIf
     
      dxtf\Release()
    EndIf
   
    ;CoUninitialize_() ; dosn't work with this ?!?
  EndIf
 
  If Success:ProcedureReturn result:EndIf
  ProcedureReturn #False

EndProcedure

;: ============================================================================

;: Get the wallpaper filename with path

WallPaper.s = Space(#MAX_PATH)
SystemParametersInfo_(#SPI_GETDESKWALLPAPER, #MAX_PATH, WallPaper, 0)

;: Load the image
Image = LoadImageEx(#PB_Any, WallPaper)

;: Test to show the image

OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_SizeGadget)

ImageGadget(1, 0, 0, 640, 480, ImageID(Image))
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 59999)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      Quit = #True

    Case #PB_Event_Menu
      Select EventMenu()
        Case 59999
          Quit = #True
      EndSelect
      
  EndSelect
  
Until Quit
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Grab desktop wallpaper to image?

Post by Dude »

netmaestro wrote:May I ask why a JPG image is no good?
Mainly because UseJPEGImageDecoder() adds 127 KB to my exe size when a simple BitBlt_() call should do the same thing.

Basically, kvitaliy's solution above would be 100% perfect if I didn't have to open a window.

I can easily do what I want already, but WITH the desktop icons included. :( So there must be a way to grab WITHOUT toggling the icons off first, surely?
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Grab desktop wallpaper to image?

Post by Bisonte »

Have you read NM's or my post ?

That is a way to load the original desktop wallpaper to an image !
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
firace
Addict
Addict
Posts: 947
Joined: Wed Nov 09, 2011 8:58 am

Re: Grab desktop wallpaper to image?

Post by firace »

Give this one a try.
No wallpaper path, no JPG decoder, no open windows, no desktop icons. :)
(Tested on Windows 10)

Code: Select all

ExamineDesktops()
CreateImage(1,DesktopWidth(0),DesktopHeight(0))
PaintDesktop_(StartDrawing(ImageOutput(1)))
StopDrawing()
SaveImage(1,"tada.bmp")
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: Grab desktop wallpaper to image?

Post by Bisonte »

very nice ;)
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Grab desktop wallpaper to image?

Post by Dude »

Bisonte wrote:Have you read NM's or my post ?

That is a way to load the original desktop wallpaper to an image !
Yes, and both posts don't satisfy the criteria that I asked. Are you aware that your desktop can have a wallpaper image WITHOUT a file on disk for it? Maybe you've never seen that, but I have. So I can't rely on trying to get the image from a file that might not be there anymore. That's why I'm asking if anyone knows a way to get the image without a file.

@firace: Thanks, but that just gives a black BMP image here on Win 7.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4995
Joined: Sun Apr 12, 2009 6:27 am

Re: Grab desktop wallpaper to image?

Post by RASHAD »

Try

Code: Select all

ExamineDesktops()

hWnd = FindWindow_("ProgMan", 0)
hBitmap = CreateImage(0, DesktopWidth(0), DesktopHeight(0),24)
hdc = StartDrawing(ImageOutput(0))
     SelectObject_(hdc, hBitmap)
     BitBlt_(hdc, 0, 0,DesktopWidth(0), DesktopHeight(0), GetWindowDC_(hWnd), 0, 0, #SRCCOPY)
StopDrawing()

SaveImage(0,GetHomeDirectory()+"test.bmp")
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Grab desktop wallpaper to image?

Post by Dude »

Hi Rashad, that's close, but your solution still shows the desktop icons. :( I thought I fixed it but it still fails in some situations.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4995
Joined: Sun Apr 12, 2009 6:27 am

Re: Grab desktop wallpaper to image?

Post by RASHAD »

Hi Dude
Try

Code: Select all

ExamineDesktops()

hWnd = FindWindow_("ProgMan", 0)
hBitmap = CreateImage(0, DesktopWidth(0), DesktopHeight(0),24)
If OSVersion() < #PB_OS_Windows_10 
  shWnd = GetWindow_(hWnd, #GW_CHILD)
  ShowWindow_(shWnd,#SW_HIDE)
EndIf
hdc = StartDrawing(ImageOutput(0))
     SelectObject_(hdc, hBitmap)
     BitBlt_(hdc, 0, 0,DesktopWidth(0), DesktopHeight(0), GetWindowDC_(hWnd), 0, 0, #SRCCOPY)
StopDrawing()
If OSVersion() < #PB_OS_Windows_10
  ShowWindow_(shWnd,#SW_SHOW)
EndIf
SaveImage(0,GetHomeDirectory()+"test.bmp")
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Grab desktop wallpaper to image?

Post by Dude »

Hi Rashad. :) It's weird. Your code works on Win 7 now but ONLY when I'm logged in as a limited user. When I tried it with an admin account, it saves the current foreground window instead (the PureBasic IDE). Thanks anyway.
Post Reply