วิธีดาวน์โหลดรูปภาพจาก url


106

มีวิธีดาวน์โหลดรูปภาพโดยตรงจาก 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

คำตอบ:


139

เพียงแค่ คุณสามารถใช้วิธีการต่อไป

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

}

หมายเหตุ: ArgumentException อาจถูกโยนทิ้งImage.FromStreamหากเนื้อหาที่ดาวน์โหลดไม่ใช่ประเภทรูปภาพที่รู้จัก

ตรวจสอบข้อมูลอ้างอิงนี้ใน MSDNเพื่อค้นหารูปแบบทั้งหมดที่มี นี่คือการอ้างอิงถึงและWebClientBitmap


2
โปรดทราบว่าคุณต้อง "ใช้ System.Drawing;" สำหรับ Image.FromStream ()
dlchambers

3
โปรดทราบว่าแทนที่จะขอให้ไลบรารีภาพตรวจจับรูปแบบภาพคุณยังสามารถดูที่ส่วนหัวของการตอบสนองเพื่อดูว่าแหล่งที่มาคิดว่าภาพใช้รูปแบบใดwebClient.ResponseHeaders["Content-Type"]
bikeman868

นอกจากนี้ยังจะเป็นหน่วยความจำประสิทธิภาพมากขึ้นกว่าการขยายการบีบอัดภาพลงในวัตถุ Bitmap ไม่มีการบีบอัดและจะช่วยให้คุณสามารถบันทึกภาพในรูปแบบเดิมด้วยการบีบอัดเดิม ฯลฯ
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);
        }
    }
}

13

ไม่จำเป็นต้องใช้System.Drawingเพื่อค้นหารูปแบบภาพใน URI System.Drawingไม่สามารถใช้งานได้.NET Coreเว้นแต่คุณจะดาวน์โหลดแพ็คเกจ System.Drawing.Common NuGetดังนั้นฉันจึงไม่เห็นคำตอบข้ามแพลตฟอร์มที่ดีสำหรับคำถามนี้

นอกจากนี้ตัวอย่างของฉันไม่ได้ใช้System.Net.WebClientเนื่องจากMicrosoft ไม่สนับสนุนการใช้System.Net.WebClientไฟล์.

เราไม่แนะนำให้คุณใช้WebClientคลาสสำหรับการพัฒนาใหม่ ให้ใช้คลาส System.Net.Http.HttpClientแทน

ดาวน์โหลดภาพจาก URL และเขียนลงในไฟล์ (ข้ามแพลตฟอร์ม) *

* ไม่มีเก่าSystem.Net.WebClientและSystem.Drawing.

วิธีนี้จะดาวน์โหลดรูปภาพแบบอะซิงโครนัส (หรือไฟล์ใดก็ได้ตราบเท่าที่ URI มีนามสกุลไฟล์) โดยใช้ไฟล์System.Net.Http.HttpClientแล้วเขียนลงในไฟล์โดยใช้นามสกุลไฟล์เดียวกับรูปภาพใน URI

รับนามสกุลไฟล์

ส่วนแรกของการรับนามสกุลไฟล์คือการลบส่วนที่ไม่จำเป็นทั้งหมดออกจาก URI
เราใช้Uri.GetLeftPart ()กับ UriPartial.Path เพื่อรับทุกอย่างตั้งแต่Schemeไฟล์Path.
ในคำอื่น ๆจะกลายเป็น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 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(50 เส้น) พร้อมกับเอกสารอื่น ๆ ที่ถูกต้อง reuses HttpClientและต้องพ้นจากมันที่คุณสามารถหาที่นี่

5

.net Framework อนุญาตให้ PictureBox Control โหลดรูปภาพจาก url

และบันทึกภาพใน Laod Complete Event

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

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

4

ลองใช้มันได้ผลสำหรับฉัน

เขียนสิ่งนี้ใน Controller ของคุณ

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.