サイトから画像をダウンロードしようとしています。私が使用しているコードは、画像が利用できる間は正常に機能しています。画像が利用できない場合は、問題が発生しています。画像の可用性を検証する方法は?
コード:
方法1:
WebRequest requestPic = WebRequest.Create(imageUrl);
WebResponse responsePic = requestPic.GetResponse();
Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error
webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg");
方法2:
WebClient client = new WebClient();
Stream stream = client.OpenRead(imageUrl);
bitmap = new Bitmap(stream); // Error : Parameter is not valid.
stream.Flush();
stream.Close();
client.dispose();
if (bitmap != null)
{
bitmap.Save("D:\\Images\\" + fileName + ".jpg");
}
編集:
ストリームには次のステートメントがあります。
Length '((System.Net.ConnectStream)(str)).Length' threw an exception of type 'System.NotSupportedException' long {System.NotSupportedException}
Position '((System.Net.ConnectStream)(str)).Position' threw an exception of type 'System.NotSupportedException' long {System.NotSupportedException}
ReadTimeout 300000 int
WriteTimeout 300000 int
画像クラスを使用する必要はありません。単に WebClient.DownloadFile
:
string localFilename = @"c:\localpath\tofile.jpg";
using(WebClient client = new WebClient())
{
client.DownloadFile("http://www.example.com/image.jpg", localFilename);
}
更新
ファイルが存在するかどうかを確認し、存在する場合はファイルをダウンロードするため、同じリクエスト内でこれを行うことをお勧めします。そのため、これを行うメソッドを次に示します。
private static void DownloadRemoteImageFile(string uri, string fileName)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Check that the remote file was found. The ContentType
// check is performed since a request for a non-existent
// image file might be redirected to a 404-page, which would
// yield the StatusCode "OK", even though the image was not
// found.
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect) &&
response.ContentType.StartsWith("image",StringComparison.OrdinalIgnoreCase))
{
// if the remote file was found, download oit
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(fileName))
{
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
}
簡単に言えば、ファイルを要求し、応答コードがOK
、Moved
、またはRedirect
のいずれかであることを確認しますおよびContentType
は画像です。これらの条件に該当する場合、ファイルがダウンロードされます。
上記のFredrikのコードを少し変更してプロジェクトで使用しました。
private static bool DownloadRemoteImageFile(string uri, string fileName)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception)
{
return false;
}
// Check that the remote file was found. The ContentType
// check is performed since a request for a non-existent
// image file might be redirected to a 404-page, which would
// yield the StatusCode "OK", even though the image was not
// found.
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect) &&
response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
{
// if the remote file was found, download it
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(fileName))
{
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
return true;
}
else
return false;
}
主な変更点は次のとおりです。
DownloadDataメソッドを使用することも可能
private byte[] GetImage(string iconPath)
{
using (WebClient client = new WebClient())
{
byte[] pic = client.DownloadData(iconPath);
//string checkPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +@"\1.png";
//File.WriteAllBytes(checkPath, pic);
return pic;
}
}
private static void DownloadRemoteImageFile(string uri, string fileName)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if ((response.StatusCode == HttpStatusCode.OK ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.Redirect) &&
response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
{
using (Stream inputStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite(fileName))
{
byte[] buffer = new byte[4096];
int bytesRead;
do
{
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
}
サーバーまたはWebサイトからイメージをダウンロードしてローカルに保存するベストプラクティス。
WebClient client=new Webclient();
client.DownloadFile("WebSite URL","C:\\....image.jpg");
client.Dispose();