10 votes

Comment télécharger une image depuis une URL vers un répertoire local ?

J'utilise C++ sans .NET sur Win32, comment puis-je télécharger une image par HTTP à partir d'un site web sans avoir à réinventer la roue ? Existe-t-il une API ou une bibliothèque qui fournit une fonction unique pour ce faire ?

http://mywebsite/file.imgext --> C:\path\to\dir\file.imgext

8voto

user672951 Points 261

Les API WinInet sont plus faciles que vous ne le pensez

Voici un programme complet de console win32. Il peut être construit avec VS 2010 Express et en téléchargeant le SDK de Windows pour obtenir WinInit.


// imaged.cpp : Defines the entry point for the console application.
//
// Copy file from internet onto local file
//      Uses Wininet API
//    program takes 1 mandatory command line argument - URL string
//    it downloads ito the current directory, or whatever is passed
//    as the second parameter to DownloadURLImage.
//    optional parameter, the name of the file (excluding path), by default it uses the
//    filename from the URL string.

#include "stdafx.h"
#include <iostream>
#include <windows.h> 
#include <WinInet.h>  // from SDK
#include "string.h"
//#include<TCHAR.H>
//#include "Tchar.h"
using namespace std ;

int convertURLtofname (TCHAR * szURL, TCHAR * szname )
// extract the filename from the URL 
{
    char aszfilename [100];
    HRESULT result;
    char achar[3], aszURL [100];
    size_t nchars, i, j;
    int fresult;

    fresult = 0;

    nchars= _tcslen(szURL);
    i= nchars -1;
    while ((i > 0) && (szURL[i] != '/') && (szURL[i] != '\\'))  {i--;}
    j= 0; i++;
    while (i < nchars) { szname [j++]= szURL[i++]; }
    szname[j]=_T('\0');

//  wcstombs ( aszfilename, szname, 100 );
//     cout << aszfilename << endl;
//----------------------------------------------
    return fresult ;
}

int determinepathfilename (TCHAR * szURL, TCHAR * szpath, TCHAR * szname, TCHAR * szpathfilename)
{  
// use path and filename when supplied.  If filename (e.g. funkypic.jpg) is not supplied, then the
// filename will be extracted from the last part of the URL
    int result ;
    result= 0;
    TCHAR szname_copy [100] ;

       if ((szname == NULL) || (szname[0] == '\0'))
            convertURLtofname (szURL, szname_copy);
       else
            _tcscpy (szname_copy, szname);

        if ((szpath == NULL) || (szpath[0] == '\0'))
                _tcscpy (szpathfilename, szname_copy);
        else
        {
            _tcscpy (szpathfilename, szpath);
            _tcscat (szpathfilename, szname_copy);
        }
    return result ;
}

bool GetFile (HINTERNET hOpen, // Handle from InternetOpen()
                    TCHAR *szURL,        // Full URL
                    TCHAR * szpath,
                    TCHAR * szname)   
{
    DWORD dwSize;
    TCHAR szHead[15];
    BYTE * szTemp[1024];
    HINTERNET  hConnect;
    FILE * pFile;
    TCHAR  szpathfilename [100] ;

    szHead[0] = '\0';

    if ( !(hConnect = InternetOpenUrl( hOpen, szURL, szHead, 15, INTERNET_FLAG_DONT_CACHE, 0)))
    {
        std::cout << "Error: InternetOpenUrl" << std::endl;
        return 0;
    }

    determinepathfilename (szURL, szpath, szname, szpathfilename);

    if  ( !(pFile = _tfopen (szpathfilename, _T("wb") ) ) )
    {
        std::cerr << "Error _tfopen" << std::endl;
        return false;
    }
    do
    {
        // Keep copying in 1024 bytes chunks, while file has any data left.
        // Note: bigger buffer will greatly improve performance.
        if (!InternetReadFile (hConnect, szTemp, 1024,  &dwSize) )
        {
            fclose (pFile);
            std::cerr << "Error InternetReadFile" << std::endl;
            return FALSE;
        }
        if (!dwSize)
            break;  // Condition of dwSize=0 indicate EOF. Stop.
        else
            fwrite(szTemp, sizeof (BYTE), dwSize , pFile);
    }   // do
    while (TRUE);
    fflush (pFile);
    fclose (pFile);

    return TRUE;
}

int DownloadURLImage (TCHAR * szURL, TCHAR * szpath, TCHAR * szname)
{   int result ;

    HINTERNET hInternet;

    result= 0;

    hInternet= InternetOpen (_T("imaged"),
                                INTERNET_OPEN_TYPE_DIRECT,  //__in  DWORD dwAccessType
                                NULL,                       //__in  LPCTSTR lpszProxyName,
                                NULL,                       //__in  LPCTSTR lpszProxyBypass,
                                NULL                        //_in   DWORD dwFlags
                            );

    GetFile (hInternet, szURL, szpath, szname) ; 
    InternetCloseHandle(hInternet);
    return result ;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc == 2)
    {
        DownloadURLImage (argv[1], NULL, NULL);
        //DownloadURLImage (argv[1], _T"C:/", NULL);
    }
    else if (argc == 3)
    {
        DownloadURLImage (argv[1], NULL, argv[2]);
        //DownloadURLImage (argv[1], _T"C:/", argv[2]);
    }
    else
    {
        cout << "Usage: imaged <image URL>" << endl ;
    }
    system("pause") ;
    return 0;
}

7voto

leen Points 1200

Vous pourriez utiliser cURLpp

Je ne l'ai pas encore utilisé, mais exemple20 On dirait que ça pourrait résoudre votre problème.

4voto

Jonathan Leaders Points 317

Si vous voulez une solution FACILE, utilisez cette phrase étonnamment simple :

system("C:\\Path\\To\\Wget\\wget.exe http://pixelcaster.com/yosemite/webcams/ahwahnee2.jpg -O C:\\Users\\Me\\Desktop\\ahwahnee2.jpg");

Avec wget pour Windows

choco install wget

Voir chocolatey.org

2voto

Sunny Milenov Points 10978

2voto

CLaRGe Points 1055

Vous pourriez utiliser le WinInet o WinHTTP en C++. Il s'agit d'API Win32 natives qui permettent d'abstraire une partie du travail d'envoi et de réception de fichiers depuis l'Internet.

J'ai utilisé WinInet avec beaucoup de succès pour faire exactement ce que vous essayez de faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X