AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Window to the World - Panoramio Wallpaper Changer

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
3D-Grabber



Joined: 07 May 2007
Posts: 4
Location: Zurich - Switzerland

PostPosted: Tue May 08, 2007 4:18 pm    Post subject: Window to the World - Panoramio Wallpaper Changer Reply with quote

Window to the World - Panoramio Wallpaper Changer

Panoramio is a community driven photo sharing service. The photos can be geotagged. There is a Panoramio layer on Google Earth and Google Maps which shows the photos on the globe. There are over 2 million photos online, most of them very good quality.

This script puts every now then a new Panoramio photo on your desktop (interval adjustable - default 5 minutes). Photos are annotated with title, location, author, ... (customizable). Only photos that can be reasonably displayed on the screen are choosen (size / aspect ratio). The script uses the ImageMagick command line tool to process the photos (Freeware, bundled with the .zip), Titan's XPath (thanks) and some other code snippets from his site.
And no, it does not use "Active Desktop" (eek..!)

Version 0.8
Download: www.autohotkey.net/3D-Grabber/WttW.zip
(just unpack and place anywhere)
only tested on XP MCE so far...

no options dialog yet! edit WttW.ini directly

in the pipeline:

- options dialog
- prefetch photos, next button
- open in browser button (see photo on panoramio.com)
- open in google earth button (if installed)
- favorites

feedback and suggestions welcome!

greets
3D


Code:


#SingleInstance ignore
#Include %A_ScriptDir%\Include
#Include XPath.ahk


Menu, Tray, Icon, WttW.ico

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MainLoop:

  ImageNo            := DownloadRandomImage()
  ConvertedImagePath := ConvertImage(ImageNo)
  UpdateWallpaper(ConvertedImagePath)
  DeletePastImages(ImageNo)
 
  Sleep, GetOption("Interval") * 1000

Goto MainLoop

ExitApp   

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UpdateWallpaper(ConvertedImagePath)
{
  RegWrite, REG_SZ, HKEY_CURRENT_USER, Control Panel\Desktop, Wallpaper, %ConvertedImagePath%
  Run, %A_WinDir%\System32\RUNDLL32.EXE user32.dll`,UpdatePerUserSystemParameters
 
  Info := CreateInfoString(ImageNoFromFileName(ConvertedImagePath))
  Info := RegExReplace(Info," - ","`n")
  Menu, Tray, Tip, %Info%
}


DeletePastImages(ImageNo)
{
  Loop, %A_ScriptDir%\Photos\*.*
  {
    Filename := RegExReplace(A_LoopFileName,"." A_LoopFileExt "$","")
    if (Filename != ImageNo)
      FileDelete, %A_LoopFileFullPath%
  }
}

ConvertImage(ImageNo)
{
   
  JpgFile := JpgFileOf(ImageNo)
  BmpFile := BmpFileOf(ImageNo)
 
  GetScreenDimensions(ScreenX, ScreenY, ScreenW, ScreenH)
  GetTaskbarDimensions(TaskbarX, TaskbarY, TaskbarW, TaskbarH)
  GetVisibleDesktopDimensions(DesktopX, DesktopY, DesktopW, DesktopH)
 
  ; ===================== create Background ====================
 
  If (GetOption("NothingBehindTaskbar") = "true")
  {
    BgW := DesktopW
    BgH := DesktopH
  }
  else
  {
    BgW := ScreenW
    BgH := ScreenH
  }

  BackgroundCmd := "-size " BgW "x" BgH " xc:black "
   
  ; ===================== Resize =======================
 
  ImgTargetW := ReadImageInfo(ImageNo,"ConvertedHorizontalResolution")
  ImgTargetH := ReadImageInfo(ImageNo,"ConvertedVerticalResolution")
 
  ResizeCmd := "( " JpgFile " -resize " ImgTargetW "x" ImgTargetH "! ) "
 
  ; ===================== compose resized img over bg =======================
 
  ComposeBgImgCmd := "-gravity center -composite "
 
  ; ===================== overlay info string ======================
 
  If(GetOption("ShowInfo") = "true")
  {
    InfoString := CreateInfoString(ImageNo)
    InfoString := " " InfoString " "   ; for box style
   
    FileDelete, InfoString.txt
    FileAppend, %InfoString%, InfoString.txt
   
    InfoPosition := GetOption("InfoPosition")
    InfoDist     := GetOption("InfoBorderDistance")
   
    dx := "+0"
    dy := "+0"
   
    if(InStr(InfoPosition,"South") || InStr(InfoPosition,"North"))
      dy := "+" InfoDist
   
    if(InStr(InfoPosition,"West") || InStr(InfoPosition,"East"))
      dx := "+" InfoDist
   
    InfoStyle := GetOption("InfoStyle")
   
    if (InfoStyle = "Outline")
    {
      Outline := "-stroke #000000 -strokewidth 3 -annotate " dx dy " @InfoString.txt "
      Stroke  := "-stroke none -fill #FFFFFF -annotate " dx dy " @InfoString.txt "
      InfoStyleCmd := Outline Stroke " "
    }
    else if (InfoStyle = "Box")
    {
      InfoStyleCmd := "-fill white -box #00000080 -annotate " dx dy " @InfoString.txt "
    }
 
    TextSize:=GetOption("InfoTextSize")
    InfoStringCmd := "-encoding unicode -gravity " InfoPosition " -pointsize " TextSize " " InfoStyleCmd
  }
  else
    InfoStringCmd := ""
 
  ; ===================== create Taskbar Background ====================

  If (GetOption("NothingBehindTaskbar") = "true")
    TBBGCmd := "( -size " ScreenW "x" ScreenH " xc:black ) +swap -gravity None -geometry +" DesktopX "+" DesktopY " -composite "
  else
    TBBGCmd := ""
 
  ; ===================== assemble command ====================

  Command := A_ScriptDir "\ImageMagick\convert " BackgroundCmd ResizeCmd ComposeBgImgCmd InfoStringCmd TBBGCmd BmpFile
 
  ;MsgBox %Command%
 
  ; ===================== run command ====================
 
  FileDelete, conv.cmd                ; just to be sure
  FileAppend, %Command%, conv.cmd
  RunWait, conv.cmd ,,Hide
 
  if (ErrorLevel)
    return 0
   
  ; ===================== delete tmp files ====================
 
  FileDelete, conv.cmd
  FileDelete, InfoString.txt

  return BmpFile
 
}


CreateInfoString(ImageNo)
{
    InfoString := ""
   
    If(GetOption("ShowInfoImageNo") = "true")
      InfoString := InfoString "#" FormatInteger(ImageNo) " - "
     
    If(GetOption("ShowInfoTitle") = "true" && !InStr(ReadImageInfo(ImageNo,"Title"),"untitled") && StrLen(ReadImageInfo(ImageNo,"Title")) > 0  )
      InfoString := InfoString ReadImageInfo(ImageNo,"Title") " - "

    If(GetOption("ShowInfoLocation") = "true" && StrLen(ReadImageInfo(ImageNo,"Location")) > 0)
      InfoString := InfoString ReadImageInfo(ImageNo,"Location") " - "
   
    If(GetOption("ShowInfoAuthor") = "true" && StrLen(ReadImageInfo(ImageNo,"Author")) > 0)
      InfoString := InfoString "by " ReadImageInfo(ImageNo,"Author") " - "
     
    If(GetOption("ShowInfoResolution") = "true")
      InfoString := InfoString ReadImageInfo(ImageNo,"HorizontalResolution") "x"  ReadImageInfo(ImageNo,"VerticalResolution") " - "
     
    If(GetOption("ShowInfoLatLon") = "true")
    {
      lat := ReadImageInfo(ImageNo,"Latitude")
      lon := ReadImageInfo(ImageNo,"Longitude")
      latlonavailable := RegExMatch(lat, "\d") * RegExMatch(lon, "\d") ; test if lat/lon contain at least one digit 
      if (latlonavailable)
      {
        latlon := "lat " lat "° lon " lon "°"
        InfoString := InfoString latlon " - "
      }
    }

    If(GetOption("ShowInfoViews") = "true")
      InfoString := InfoString "viewed " ReadImageInfo(ImageNo,"Views") "x - "
     
    return RegExReplace(InfoString," - $","")  ; cut final -
}




DownloadRandomImage()
{
  NewestKnownImage       := GetOption("NewestKnownImage")
  NoOfConnectionAttempts := GetOption("NoOfConnectionAttempts")
 
  MaxImageNo := NewestKnownImage*1.1
  Attempt := 1
 
RetryAnotherOne:
 
  Random, ImageNo, 1, %MaxImageNo%
  ImageNo := Floor(ImageNo)         
 
RetryToConnect:
 
  ImgInfoResult := GetImageInfo(ImageNo, Title, Location, Author, ImgW, ImgH, Lat, Lon, Views)
 
 
  ;========================= connection ==========================
 
  if (ImgInfoResult = "ErrFailedToConnect")
  {
    if (Attempt <= NoOfConnectionAttempts)
    {
      Attempt++
      Goto RetryToConnect
    }
    Else
      return 0
  }

  ; ========================= handle not existing ==========================
 
  if (ImgInfoResult = "ErrImageDoesNotExist")    ; retry with another one
    Goto RetryAnotherOne
 
  ; ========================== newest img discovered =====================
 
  if (ImageNo > NewestKnownImage)
  {
    NewestKnownImage := ImageNo
    SetOption("NewestKnownImage", NewestKnownImage)
  }

  ; ======================== filter ================================
 
  if (GetOption("OnlyGeoTagged") = "true" && StrLen(Lat)*StrLen(Lon) = 0 )
  {
    Discarded := GetOption("ImagesRefused"), Discarded++, SetOption("ImagesRefused", Discarded)
    Goto RetryAnotherOne
  }

  ; ======================== geometry constraints =====================

  if (!CheckTransformationConstraints(ImgW, ImgH, ConvertedW, ConvertedH))
  {
    Discarded := GetOption("ImagesRefused"), Discarded++, SetOption("ImagesRefused", Discarded)
    Goto RetryAnotherOne
  }

  ; ====================== Download full size image =========================
 
  ImagePath := JpgFileOf(ImageNo)
 
  UrlDownloadToFile, http://www.panoramio.com/photos/original/%ImageNo%.jpg, %ImagePath%
  if (ErrorLevel)
    return 0
   
  ImgRead := GetOption("ImagesAccepted"), ImgRead++, SetOption("ImagesAccepted", ImgRead)
   
  ; ====================== write image ini file ============================ 
   
  WriteImageInfo(ImageNo, "Title" ,                         Title)
  WriteImageInfo(ImageNo, "Location" ,                      Location)
  WriteImageInfo(ImageNo, "Author" ,                        Author)
  WriteImageInfo(ImageNo, "HorizontalResolution" ,          ImgW)
  WriteImageInfo(ImageNo, "VerticalResolution" ,            ImgH)
  WriteImageInfo(ImageNo, "ConvertedHorizontalResolution" , ConvertedW)
  WriteImageInfo(ImageNo, "ConvertedVerticalResolution" ,   ConvertedH)
  WriteImageInfo(ImageNo, "Latitude" ,                      Lat)
  WriteImageInfo(ImageNo, "Longitude" ,                     Lon)
  WriteImageInfo(ImageNo, "Views" ,                         Views)
   
  return ImageNo
}



CheckTransformationConstraints(SourceW, SourceH, ByRef ConvertedW, ByRef ConvertedH)
{
 
  ;========================== min size constraints ============================
 
  If(SourceW < GetOption("MinHorizontalSize") || SourceH < GetOption("MinVerticalSize"))
    return 0
 
  ;========================== aspect ratio constraints ============================
 
  GetScreenDimensions(ScreenX, ScreenY, ScreenW, ScreenH)
  GetVisibleDesktopDimensions(DesktopX, DesktopY, DesktopW, DesktopH)
 
  if (GetOption("NothingBehindTaskbar") = "true" )
  {
    TargetW := DesktopW
    TargetH := DesktopH
  } 
  else
  {
    TargetW := ScreenW
    TargetH := ScreenH
  }   

  SourceRatio := SourceW / SourceH
  TargetRatio := TargetW / TargetH
 
  MaxHorizontalStretch := RegExReplace(GetOption("MaxHorizontalStretch"),"\D","") / 100  ; remove % sign
  MaxVerticalStretch   := RegExReplace(GetOption("MaxVerticalStretch")  ,"\D","") / 100
  MaxHorizontalBlack   := RegExReplace(GetOption("MaxHorizontalBlack")  ,"\D","") / 100
  MaxVerticalBlack     := RegExReplace(GetOption("MaxVerticalBlack")    ,"\D","") / 100
   
 
  if (TargetRatio > SourceRatio)
  {                 
   
    x:= (1 + MaxHorizontalStretch)/(1 - MaxVerticalBlack)
   
    ;srx:=SourceRatio * x
    ;MsgBox TargetRatio %TargetRatio% > SourceRatio %SourceRatio% x= %x% SR * x = %srx%   
   
    if(SourceRatio * x >= TargetRatio)
    {
      ConvertedW := Floor( (TargetH / SourceH) * SourceW  * (1 + MaxHorizontalStretch) ) ; stretch it to the max
      if(ConvertedW > TargetW)
        ConvertedW := TargetW
     
      ConvertedH := TargetH 
      return 1             
    }
    else
      return 0
  }
  else
  {
    x:= (1 + MaxVerticalStretch)/(1 - MaxHorizontalBlack)
   
    ;srx:=SourceRatio / x
    ;MsgBox TargetRatio %TargetRatio% < SourceRatio %SourceRatio% x= %x% SR / x = %srx%   
   
    if(SourceRatio / x <= TargetRatio )
    {
      ConvertedW := TargetW     
      ConvertedH := Floor( (TargetW / SourceW) * SourceH *(1 + MaxVerticalStretch) )   ; stretch it to the max
      if(ConvertedH > TargetH)
        ConvertedH := TargetH
     
      return 1
    }
    else
      return 0
  }
}

FormatInteger(_number)
{
  local fn, fnl

  fnl := StrLen(_number) * 2   ; More than enough...
  VarSetCapacity(fn, fnl)
  DllCall("GetNumberFormat", "UInt", 0x400, "UInt", 0, "Str", _number, "UInt", 0, "Str", fn, "Int", fnl)

  StringTrimRight, trim ,fn, 3
  Return trim
}


GetOption(name)
{
  IniRead, ReturnVar, WttW.ini, Settings, %name%
  return ReturnVar 
}


SetOption(name,value)
{
  IniWrite, %value%, WttW.ini, Settings, %name%
  return ErrorLevel
}

ImageNoFromFileName(FileName)
{
  RegExMatch(FileName,"(\d+).*?$",s)   
   ImageNo := s1
  return ImageNo
}

IniFileOf(FileNameOrImageNo)
{
  ImageNo := ImageNoFromFileName(FileNameOrImageNo)
  IniFile := A_ScriptDir "\Photos\" ImageNo ".ini"
  return IniFile
}

BmpFileOf(FileNameOrImageNo)
{
  ImageNo := ImageNoFromFileName(FileNameOrImageNo)
  BmpFile := A_ScriptDir "\Photos\" ImageNo ".bmp"
  return BmpFile
}

JpgFileOf(FileNameOrImageNo)
{
  ImageNo := ImageNoFromFileName(FileNameOrImageNo)
  JpgFile := A_ScriptDir "\Photos\" ImageNo ".jpg"
  return JpgFile
}

WriteImageInfo(ImageNoOrName, Field, Value)
{
   IniFile := IniFileOf(ImageNoOrName)   
   IniWrite, %Value%, %IniFile%, Info, %Field%
   return ErrorLevel
}

ReadImageInfo(ImageNoOrName, Field)
{
  IniFile := IniFileOf(ImageNoOrName)
  IniRead, Value, %IniFile%, Info, %Field%
  return Value
}


GetScreenDimensions(ByRef ScreenX, ByRef ScreenY, ByRef ScreenW, ByRef ScreenH)
{
  WinGetPos, ScreenX, ScreenY, ScreenW, ScreenH, Program Manager
}



GetTaskbarDimensions(ByRef TaskbarX, ByRef TaskbarY, ByRef TaskbarW, ByRef TaskbarH)
{

  WinGetPos TaskbarX, TaskbarY, TaskbarW, TaskbarH, ahk_class Shell_TrayWnd
  GetScreenDimensions(ScreenX, ScreenY, ScreenW, ScreenH) 
 
  ; ======== 'crop' if taskbar bigger than screen (classic theme in xp) ====
 
  if (TaskbarX < ScreenX)
    TaskbarX := ScreenX
 
  if (TaskbarY < ScreenY)
     TaskbarY := ScreenY
 
  if( TaskbarX + TaskbarW > ScreenX + ScreenW )
     TaskbarW := ScreenX + ScreenW - TaskbarX
 
  if( TaskbarY + TaskbarH > ScreenY + ScreenH )
     TaskbarH := ScreenY + ScreenH - TaskbarY
     
  ; ========
 
}



GetVisibleDesktopDimensions(ByRef DesktopX, ByRef DesktopY, ByRef DesktopW, ByRef DesktopH)
{
 
  ; ========================= get screen and taskbar dims =======================
 
  GetScreenDimensions(ScreenX, ScreenY, ScreenW, ScreenH)
  GetTaskbarDimensions(TaskbarX, TaskbarY, TaskbarW, TaskbarH)
 
  ; ========================= defaults image size/dims =========================
 
  DesktopX := ScreenX, DesktopY := ScreenY, DesktopW := ScreenW, DesktopH := ScreenH
 
  ; ========================= HORIZONTAL TASKBAR =========================
 
  if(TaskbarW = ScreenW) ; taskbar has same width as desktop
  {
     DesktopH := ScreenH - TaskbarH
     
     if( TaskbarY = ScreenY )      ;Top position
        DesktopY := ScreenY + TaskbarH
  }
 
  ; ========================= VERTICAL TASKBAR =========================
 
  if( TaskbarH = ScreenH ) ; taskbar has same height as desktop
  {
    DesktopW := ScreenW - TaskbarW   
     
     if( TaskbarX = ScreenX )
        DesktopX := ScreenX + TaskbarW    ; left position
  }
}






GetImageInfo(ImageNumber, ByRef Title, ByRef Location, ByRef Author,ByRef DimX, ByRef DimY, ByRef Lat, ByRef Lon, ByRef Views)
{
   ; =============== download preview doc ================
 
  UrlDownloadToFile, http://www.panoramio.com/photo/%ImageNumber%, page.html
   if (ErrorLevel)
    return "ErrFailedToConnect"
   
   ; =============== read file =====================
 
  FileRead, Page, page.html
  xml := XmlDoc("page.html") ; load as XML document

  ; =============== check if image exists ==============

   if(InStr(Page,"This photo does not exist"))
      return "ErrImageDoesNotExist" 

   ; =============== extract Title ================

   tit := XPath(xml, "/html/body/div[1]/div[3]/div[1]/div[1]/img[1]/@title")
   RegExMatch(tit,"'(.*)'",t)
   Title := t1
   Title := RegExReplace(Title,",",",")
   
   ; =============== extract Location ================

   loc := XPath(xml, "/html/body/div[1]/div[3]/div[1]/div[1]/p/text()")
   PosEndDescritpion:=InStr(loc,"<") - 4
   Location := SubStr(loc,1,PosEndDescritpion)
   Location := RegExReplace(Location,",",",")

   ; =============== extract Author ================

   Author := XPath(xml, "/html/body/div[1]/div[3]/div[1]/div[1]/p[1]/a[1]/text()")
   Author := RegExReplace(Author,",",",")
      
   ; =============== extract size ================

   size := XPath(xml, "/html/body/div[1]/div[3]/div[1]/div[1]/p[1]/a[2]/@title")
   
   RegExMatch(size,"(\d+) x (\d+)",s)
   DimX := s1
   DimY := s2
   
   ; =============== extract lat/lon ================
   
   RegExMatch(Page,"abbr class='latitude' title='(.*?)'>",s)   ; the ? after * makes the latter non-greedy
   Lat := s1
   
  RegExMatch(Page,"abbr class='longitude' title='(.*?)'>",s) 
   Lon := s1
   
   ; =============== extract Views ================
   
   RegExMatch(Page,"Viewed (\d+) times",s)   
   Views := s1

  ; =============== delete tmp file ===============
 
  FileDelete, page.html

   return "OK"
}


Back to top
View user's profile Send private message
sashabe



Joined: 09 Oct 2006
Posts: 14

PostPosted: Tue Aug 14, 2007 2:23 pm    Post subject: Reply with quote

Your link does not work properly. It shows only a blank page.
Back to top
View user's profile Send private message
NioHawaii
Guest





PostPosted: Fri Aug 24, 2007 2:05 pm    Post subject: Panoramiodesktop Reply with quote

Hey i'm development this application in C , code is a bit oscenic but work good,here link :

http://sourceforge.net/projects/earthdesktop


I'm using ImageStone lib for manipulationg images..

I thought to use also jpeg size data in html pages , but butter to use these lib. If do you want to help me....
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group