Cách tải xuống hình ảnh từ url


103

Có cách nào để tải xuống hình ảnh trực tiếp từ url trong c # nếu url không có định dạng hình ảnh ở cuối liên kết không? Ví dụ về 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

Tôi biết cách tải xuống hình ảnh khi url kết thúc bằng định dạng hình ảnh. Ví dụ:

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

Câu trả lời:


134

Đơn giản, bạn có thể sử dụng các phương pháp sau.

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

Các phương pháp này gần giống như DownloadString (..) và DownloadStringAsync (...). Họ lưu trữ tệp trong Thư mục thay vì trong chuỗi C # và không cần phần mở rộng Định dạng trong URi

Nếu bạn không biết Định dạng (.png, .jpeg, v.v.) của Hình ảnh

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();
}

Sử dụng nó

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 đó là một câu hỏi hoàn toàn khác nên được tìm kiếm hoặc hỏi ở nơi khác. Chủ đề này dành cho việc tải xuống một hình ảnh.
AzNjoE

79

Tùy thuộc vào việc bạn có biết định dạng hình ảnh hay không, đây là những cách bạn có thể thực hiện:

Tải hình ảnh xuống tệp, biết định dạng hình ảnh

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

Tải hình ảnh xuống tệp mà không cần biết định dạng hình ảnh

Bạn có thể sử dụng Image.FromStreamđể tải bất kỳ loại ảnh bitmap thông thường nào (jpg, png, bmp, gif, ...), nó sẽ tự động phát hiện loại tệp và bạn thậm chí không cần kiểm tra phần mở rộng url (điều này không tốt lắm thực hành). Ví dụ:

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) ; 
       }
   } 

}

Lưu ý: ArgumentException có thể được ném ra Image.FromStreamnếu nội dung tải xuống không phải là loại hình ảnh đã biết.

Kiểm tra tham chiếu này trên MSDN để tìm tất cả các định dạng có sẵn. Đây là tham chiếu đến WebClientBitmap.


2
Lưu ý rằng bạn cần "using System.Drawing;" cho Image.FromStream ()
dlchambers

3
Lưu ý rằng thay vì hỏi các thư viện hình ảnh để phát hiện các định dạng hình ảnh bạn cũng có thể nhìn vào các tiêu đề phản ứng để xem những gì định dạng nguồn cho rằng hình ảnh được sử dụngwebClient.ResponseHeaders["Content-Type"]
bikeman868

Đây cũng sẽ là bộ nhớ hiệu quả hơn so với việc mở rộng hình ảnh nén vào một đối tượng Bitmap không nén, và sẽ cho phép bạn lưu hình ảnh trong định dạng ban đầu của nó với khả năng nén ban đầu của nó, vv
bikeman868

19

Đối với bất kỳ ai muốn tải xuống hình ảnh mà KHÔNG lưu nó vào tệp:

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

9

Không cần thiết phải sử dụng System.Drawingđể tìm định dạng hình ảnh trong URI. System.Drawingkhông khả dụng .NET Coretrừ khi bạn tải xuống gói NuGet System.Drawing.Common và do đó tôi không thấy bất kỳ câu trả lời đa nền tảng nào cho câu hỏi này.

Ngoài ra, ví dụ của tôi không sử dụng System.Net.WebClientMicrosoft rõ ràng không khuyến khích việc sử dụngSystem.Net.WebClient .

Chúng tôi khuyên bạn không nên sử dụng WebClientlớp học để phát triển mới. Thay vào đó, hãy sử dụng lớp System.Net.Http.HttpClient .

Tải xuống hình ảnh và ghi nó vào tệp mà không cần biết phần mở rộng (nền tảng chéo) *

* Không có cũ System.Net.WebClientSystem.Drawing.

Phương pháp này sẽ tải xuống không đồng bộ một hình ảnh (hoặc bất kỳ tệp nào miễn là URI có phần mở rộng tệp) bằng cách sử dụng System.Net.Http.HttpClientvà sau đó ghi nó vào một tệp, sử dụng cùng một phần mở rộng tệp như hình ảnh có trong URI.

Lấy phần mở rộng tệp

Phần đầu tiên của việc tải phần mở rộng tệp là xóa tất cả các phần không cần thiết khỏi URI.
Chúng tôi sử dụng Uri.GetLeftPart () với UriPartial.Path để tải mọi thứ từ Schemeđầu đến cuối Path.
Nói cách khác, https://www.example.com/image.png?query&with.dotstrở thànhhttps://www.example.com/image.png .

Sau đó, chúng tôi sử dụng Path.GetExtension () để chỉ lấy phần mở rộng (trong ví dụ trước của tôi, .png).

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

Đang tải xuống hình ảnh

Từ đây nó sẽ được thẳng về phía trước. Tải xuống hình ảnh bằng HttpClient.GetByteArrayAsync , tạo đường dẫn, đảm bảo thư mục tồn tại và sau đó ghi các byte vào đường dẫn bằng File.WriteAllBytesAsync () (hoặc File.WriteAllBytesnếu bạn đang sử dụng .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);
}

Lưu ý rằng bạn cần sử dụng các lệnh sau.

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

Ví dụ sử dụng

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));

Ghi chú

  • Thực tế là không tốt khi tạo mới HttpClientcho mọi lệnh gọi phương thức. Nó phải được sử dụng lại trong toàn bộ ứng dụng. Tôi đã viết một ví dụ ngắn về ImageDownloader(50 dòng) kèm theo nhiều tài liệu hơn để sử dụng lại chính xác HttpClientvà xử lý đúng cách mà bạn có thể tìm thấy ở đây .

5

.net Framework cho phép PictureBox Control tải hình ảnh từ url

và Lưu hình ảnh trong Laod Complete Event

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

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

4

Hãy thử điều này nó đã làm việc cho tôi

Viết điều này vào Bộ điều khiển của bạn

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));
        }

Đây là quan điểm của tôi

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

1

Hầu hết các bài đăng mà tôi tìm thấy sẽ hết thời gian chờ sau lần lặp thứ hai. Đặc biệt nếu bạn đang lặp lại một loạt các hình ảnh nếu như tôi đã từng. Vì vậy, để cải thiện các đề xuất ở trên, đây là toàn bộ phương pháp:

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;
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.