URL에서 이미지를 다운로드하는 방법


103

URL이 링크 끝에 이미지 형식이없는 경우 C #의 URL에서 직접 이미지를 다운로드하는 방법이 있습니까? URL의 예 :

https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d969d392b63b27ec4f4b24a

URL이 이미지 형식으로 끝날 때 이미지를 다운로드하는 방법을 알고 있습니다. 예 :

http://img1.wikia.nocookie.net/__cb20101219155130/uncyclopedia/images/7/70/Facebooklogin.png

답변:


134

간단히 다음과 같은 방법을 사용할 수 있습니다.

using (WebClient client = new WebClient()) 
{
    client.DownloadFile(new Uri(url), @"c:\temp\image35.png");
    // OR 
    client.DownloadFileAsync(new Uri(url), @"c:\temp\image35.png");
}

이러한 메서드는 DownloadString (..) 및 DownloadStringAsync (...)와 거의 동일합니다. C # 문자열이 아닌 디렉토리에 파일을 저장하며 URi에서 형식 확장자가 필요하지 않습니다.

이미지의 형식 (.png, .jpeg 등)을 모르는 경우

public void SaveImage(string filename, ImageFormat format)
{    
    WebClient client = new WebClient();
    Stream stream = client.OpenRead(imageUrl);
    Bitmap bitmap;  bitmap = new Bitmap(stream);

    if (bitmap != null)
    {
        bitmap.Save(filename, format);
    }

    stream.Flush();
    stream.Close();
    client.Dispose();
}

그것을 사용

try
{
    SaveImage("--- Any Image Path ---", ImageFormat.Png)
}
catch(ExternalException)
{
    // Something is wrong with Format -- Maybe required Format is not 
    // applicable here
}
catch(ArgumentNullException)
{   
    // Something wrong with Stream
}


4
@Arsman Ahmad는 다른 곳에서 찾아 보거나 물어봐야하는 완전히 다른 질문입니다. 이 스레드는 단일 이미지를 다운로드하기위한 것입니다.
AzNjoE

79

이미지 형식을 알고 있는지 여부에 따라 다음과 같은 방법으로 수행 할 수 있습니다.

이미지 형식을 알고 이미지를 파일로 다운로드

using (WebClient webClient = new WebClient()) 
{
   webClient.DownloadFile("http://yoururl.com/image.png", "image.png") ; 
}

이미지 형식을 모르고 이미지를 파일로 다운로드

Image.FromStream모든 종류의 일반적인 비트 맵 (jpg, png, bmp, gif, ...)을로드하는 데 사용할 수 있으며 파일 유형을 자동으로 감지하며 URL 확장자를 확인할 필요도 없습니다 (그다지 좋지 않습니다. 연습). 예 :

using (WebClient webClient = new WebClient()) 
{
    byte [] data = webClient.DownloadData("https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-xpf1/v/t34.0-12/10555140_10201501435212873_1318258071_n.jpg?oh=97ebc03895b7acee9aebbde7d6b002bf&oe=53C9ABB0&__gda__=1405685729_110e04e71d9");

   using (MemoryStream mem = new MemoryStream(data)) 
   {
       using (var yourImage = Image.FromStream(mem)) 
       { 
          // If you want it as Png
           yourImage.Save("path_to_your_file.png", ImageFormat.Png) ; 

          // If you want it as Jpeg
           yourImage.Save("path_to_your_file.jpg", ImageFormat.Jpeg) ; 
       }
   } 

}

참고 : Image.FromStream다운로드 한 콘텐츠가 알려진 이미지 유형이 아닌 경우 ArgumentException이 발생할 수 있습니다 .

사용 가능한 모든 형식을 찾으려면 MSDN에서이 참조를 확인하십시오 . 다음은 WebClient및 에 대한 참조 Bitmap입니다.


2
"using System.Drawing;"이 필요합니다. for Image.FromStream ()
dlchambers 2011

3
대신 당신은 또한 응답 헤더를 볼 수있는 이미지 포맷을 검출하기 위해 이미지 라이브러리를 묻는 원본 이미지가 사용 어떻게 생각하는지 형식으로 볼 수 있습니다webClient.ResponseHeaders["Content-Type"]
bikeman868

이것은 또한 압축되지 않은 비트 맵 객체로 압축 된 이미지를 확대보다 훨씬 더 많은 메모리를 효율적으로 할 것이고, 당신이 원래의 압축 원본 형식 등 이미지를 저장할 수 있습니다 것
bikeman868

20

파일에 저장하지 않고 이미지를 다운로드하려는 모든 사용자 :

Image DownloadImage(string fromUrl)
{
    using (System.Net.WebClient webClient = new System.Net.WebClient())
    {
        using (Stream stream = webClient.OpenRead(fromUrl))
        {
            return Image.FromStream(stream);
        }
    }
}

11

System.DrawingURI에서 이미지 형식을 찾는 데 사용할 필요는 없습니다 . System.Drawing.Common NuGet 패키지 를 다운로드하지 System.Drawing않으면 사용할 수 없으므로이 질문에 대한 좋은 크로스 플랫폼 답변이 표시되지 않습니다..NET Core

또한, 내 예는 사용하지 않기 System.Net.WebClient때문에 Microsoft는 명시 적으로의 사용을 억제System.Net.WebClient .

WebClient새로운 개발 에는 클래스를 사용하지 않는 것이 좋습니다 . 대신 System.Net.Http.HttpClient 클래스를 사용하십시오 .

확장자를 모른 채 이미지를 다운로드하여 파일에 씁니다 (크로스 플랫폼) *

* 오래된 System.Net.WebClientSystem.Drawing.

이 메서드는를 사용하여 이미지 (또는 URI에 파일 확장자가있는 한 모든 파일)를 비동기 적으로 다운로드 한 System.Net.Http.HttpClient다음 URI에있는 이미지와 동일한 파일 확장자를 사용하여 파일에 씁니다.

파일 확장자 얻기

파일 확장자를 얻는 첫 번째 부분은 URI에서 불필요한 부분을 모두 제거하는 것입니다. UriPartial.Path 와 함께 Uri.GetLeftPart ()
사용 하여 . 즉, 이된다 .SchemePath
https://www.example.com/image.png?query&with.dotshttps://www.example.com/image.png

그 후 Path.GetExtension () 을 사용 하여 확장 만 가져옵니다 (이전 예제에서는 .png).

var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
var fileExtension = Path.GetExtension(uriWithoutQuery);

이미지 다운로드

여기서부터는 간단해야합니다. HttpClient.GetByteArrayAsync로 이미지를 다운로드하고 , 경로를 만들고, 디렉터리가 있는지 확인한 다음 File.WriteAllBytesAsync () 를 사용하여 경로에 바이트를 씁니다 (또는 File.WriteAllBytes.NET Framework에있는 경우).

private async Task DownloadImageAsync(string directoryPath, string fileName, Uri uri)
{
    using var httpClient = new HttpClient();

    // Get the file extension
    var uriWithoutQuery = uri.GetLeftPart(UriPartial.Path);
    var fileExtension = Path.GetExtension(uriWithoutQuery);

    // Create file path and ensure directory exists
    var path = Path.Combine(directoryPath, $"{fileName}{fileExtension}");
    Directory.CreateDirectory(directoryPath);

    // Download the image and write to the file
    var imageBytes = await _httpClient.GetByteArrayAsync(uri);
    await File.WriteAllBytesAsync(path, imageBytes);
}

다음 using 지시문이 필요합니다.

using System;
using System.IO;
using System.Threading.Tasks;
using System.Net.Http;

사용 예

var folder = "images";
var fileName = "test";
var url = "https://cdn.discordapp.com/attachments/458291463663386646/592779619212460054/Screenshot_20190624-201411.jpg?query&with.dots";

await DownloadImageAsync(folder, fileName, new Uri(url));

노트

  • HttpClient모든 메서드 호출에 대해 새로 만드는 것은 나쁜 습관 입니다. 애플리케이션 전체에서 재사용되어야합니다. 나는 여기에서 찾을 수있는 그것을 ImageDownloader올바르게 재사용 HttpClient하고 적절하게 처리 하는 더 많은 문서와 함께 (50 줄) 의 짧은 예제를 작성했습니다 .

5

.net 프레임 워크를 사용하면 PictureBox 컨트롤이 URL에서 이미지를로드 할 수 있습니다.

및 Laod Complete Event에 이미지 저장

protected void LoadImage() {
 pictureBox1.ImageLocation = "PROXY_URL;}

void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
   pictureBox1.Image.Save(destination); }

4

나를 위해 일한 이것을 시도하십시오

컨트롤러에 이것을 작성하십시오.

public class DemoController: Controller

        public async Task<FileStreamResult> GetLogoImage(string logoimage)
        {
            string str = "" ;
            var filePath = Server.MapPath("~/App_Data/" + SubfolderName);//If subfolder exist otherwise leave.
            // DirectoryInfo dir = new DirectoryInfo(filePath);
            string[] filePaths = Directory.GetFiles(@filePath, "*.*");
            foreach (var fileTemp in filePaths)
            {
                  str= fileTemp.ToString();
            }
                return File(new MemoryStream(System.IO.File.ReadAllBytes(str)), System.Web.MimeMapping.GetMimeMapping(str), Path.GetFileName(str));
        }

여기 내 견해

<div><a href="/DemoController/GetLogoImage?Type=Logo" target="_blank">Download Logo</a></div>

1

내가 찾은 대부분의 게시물은 두 번째 반복 후에 시간 초과됩니다. 특히 내가 그랬던 것처럼 이미지를 반복하는 경우. 따라서 위의 제안을 개선하기 위해 전체 방법이 있습니다.

public System.Drawing.Image DownloadImage(string imageUrl)
    {
        System.Drawing.Image image = null;

        try
        {
            System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(imageUrl);
            webRequest.AllowWriteStreamBuffering = true;
            webRequest.Timeout = 30000;
            webRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
            webRequest.ServicePoint.MaxIdleTime = 5000;

            using (System.Net.WebResponse webResponse = webRequest.GetResponse())
            {

                using (System.IO.Stream stream = webResponse.GetResponseStream())
                {
                    image = System.Drawing.Image.FromStream(stream);
                }
            }

            webRequest.ServicePoint.CloseConnectionGroup(webRequest.ConnectionGroupName);
            webRequest = null; 
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message, ex);

        }


        return image;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.