DELPHI6.0 ブラウザ上の画像をLocalに保存するには?

解決


のり  2003-11-27 02:08:40  No: 5760  IP: [192.*.*.*]

先月、初めてDELPHIで仕事を始めている、のりといいます。
この業界に入って半年、わからぬことばかりで^^;

  今回の質問なんですが、指定したアドレスの画面の画像を
自分のローカルに保存するにはどうしたらいいのか?と言う質問なんですけど
DELPHIのコンポーネントを見ても意味がわからず^^;

何分、初心者でわからぬことばかりですが、教えてください。

編集    削除
にしの  2003-11-27 02:55:31  No: 5761  IP: [192.*.*.*]

質問が曖昧ですよ。
タイトルから読むと、
1.TWebBrowserで表示しているページ内の指定した画像を、ローカルに保存したい
2.IEなどのブラウザで表示しているページ内の指定した画像を、ローカルに保存したい
本文から読むと、
3.指定したURLの画像を、ローカルに保存したい

どれでしょうか。
3であればTCPClientで取ってくればOKです。

1,2は、IEにキャッシュがあることを期待して(なくてもいいのですが)、InternetOpenUrl APIなどで取得すればよいかと思います。
InternetOpenUrlのサンプルは、Cですが、
http://tokyo.cool.ne.jp/masapico/api_InternetOpenUrl.html
にありました。

DOMではおそらく出来ません。
# 未確認です

編集    削除
にしの  2003-11-27 02:56:55  No: 5762  IP: [192.*.*.*]

ああ、もう1つ。
3も、InternetOpenUrlで取得できます。こっちの方が簡単かも。
それと、TWebBrowserコンポーネントであれば、URLはDOMから取得できると思います。取得したURLで、InternetOpenUrlを使って画像を取得、という手順になります。

編集    削除
のり  2003-11-27 18:09:56  No: 5763  IP: [192.*.*.*]

質問がわかりにくくてすいませんでした^^;

3の指定したURLの画像をローカルに保存したいです。

回答ありがとうございます!!やってみます!!

編集    削除
のり  2003-12-01 20:25:34  No: 5764  IP: [192.*.*.*]

自分でも調べながらやっているのですが、どうもうまくいきません、というよりもやり方がわかりません。

TCPClientを使ったサンプルソースみたいな物があるとうれしいのですが、
わがままですいません。

編集    削除
にしの  2003-12-01 21:49:17  No: 5765  IP: [192.*.*.*]

HTTPに関しては、ご自身で勉強してくださいね。
例えば、
http://www.atmarkit.co.jp/fnetwork/rensai/tcp01/01.html
http://www.atmarkit.co.jp/fnetwork/rensai/tcp02/01.html
こういうサイトなど。


コーディングはこんな感じになると思います。
エラーチェックなどはご自身で用意してください。

procedure TForm1.Button1Click(Sender: TObject);
var
  buf: array[0..128] of char;
  str: String;
  len: integer;
begin
  str := '';
  TcpClient1.RemoteHost := 'www.yahoo.co.jp';
  TcpClient1.RemotePort := '80';
  Memo1.Lines.Clear;
  try
    if TcpClient1.Connect then
    begin
      TcpClient1.Sendln('GET / HTTP/1.1');
      TcpClient1.Sendln('Host: www.yahoo.co.jp');
      TcpClient1.Sendln('');
      while true do
      begin
        Application.ProcessMessages;
        begin
          len := TcpClient1.ReceiveBuf(buf[0], 128, 0);
          if len = 0 then Break;
          str := str + Copy(buf, 1, len);
        end;
      end;
      Memo1.Lines.Add(str);
    end;
  finally
    if TcpClient1.Connected then TcpClient1.Disconnect;
  end;
end;

編集    削除
のり  2003-12-01 22:26:21  No: 5766  IP: [192.*.*.*]

はい!勉強します!

細かく書いていただいてありがとうございます!!

編集    削除
のり  2003-12-01 22:31:51  No: 5767  IP: [192.*.*.*]

Memo1.Lines.Clear;

  とありますが、Memo1は何型で宣言すればいいですか?

編集    削除
にしの  2003-12-01 22:48:43  No: 5768  IP: [192.*.*.*]

TMemoを貼り付けただけです。
まあ、何でもいいんですが。

編集    削除
のり  2003-12-01 23:02:28  No: 5769  IP: [192.*.*.*]

TMemoには何が表示されるんですか?
指定したURL(www.yahoo.co.jp)の何かの情報をAdd(追加?)
し表示されるのでしょうか?

実行してみましたが。

  Memoには何も表示されないですけど、それで動作はあっていますか?

編集    削除
にしの  2003-12-01 23:09:49  No: 5770  IP: [192.*.*.*]

Application.ProcessMessages;
のあたりで、データが来るのを待たないと駄目かもしれません。
回線速度とPCの処理能力によりますが、こちらでは(PCの性能が悪いので^^;)取れています。

別なサンプル作ってみますね。
もしかしたら、IndyのTcpClientならうまくいくかもしれないので。

編集    削除
のり  2003-12-01 23:12:43  No: 5771  IP: [192.*.*.*]

すいません^^;

お願いします!!HTTPの勉強してます!!

編集    削除
にしの  2003-12-01 23:13:11  No: 5772  IP: [192.*.*.*]

Indyの、TIdHTTPですんなり行きました。

var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    IdHTTP1.Get('http://www.yahoo.co.jp/', Stream);
    Stream.Seek(0, soBeginning);
    Memo1.Lines.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

これでどうでしょうか。

編集    削除
にしの  2003-12-01 23:19:28  No: 5773  IP: [192.*.*.*]

InternetOpenUrlを使った例。

var
 hSession: HINTERNET;
 hService: HINTERNET;
 lpBuffer: array[0..1024] of Char;
 dwBytesRead: Cardinal;
 str: String;
begin
  str := '';
  hSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
  if Assigned(hSession) then
  begin
    hService := InternetOpenUrl(hSession, 'http://www.yahoo.co.jp/', nil, 0, INTERNET_FLAG_RELOAD, 0);
    try
      if Assigned(hService) then
      begin
        while true do
        begin
          FillChar(lpBuffer, SizeOf(lpBuffer), #0);
          InternetReadFile(hService, @lpBuffer, SizeOf(lpBuffer), dwBytesRead);
          if dwBytesRead = 0 then Break;
          str := str + Copy(lpBuffer, 0, dwBytesRead - 1);
        end; //while
        str := AdjustLineBreaks(str);
        Memo1.Lines.Add(str);
      end; //if Assigned(hService)
    finally
     InternetCloseHandle(hService);
    end;
  end; //if Assigned(hSession)

 finally
  InternetCloseHandle(hSession);
 end;
end;

そういえば、たかみちえさんのところにHTTPでのダウンロードを実現するコンポーネントありませんでしたっけ?

編集    削除
のり  2003-12-01 23:35:21  No: 5774  IP: [192.*.*.*]

Indyの、TIdHTTPですんなり行きました。

  TIdHTTPというコンポーネントですか?

そういえば、たかみちえさんのところにHTTPでのダウンロードを実現するコンポーネントありませんでしたっけ?

  そんな便利な物があるんですか!?

編集    削除
のり  2003-12-01 23:38:56  No: 5775  IP: [192.*.*.*]

Stream.Seek(0, soBeginning);
  
  の部分でEIdSoketErrorが発生して、うまくいかないです;;

編集    削除
のり  2003-12-01 23:41:37  No: 5776  IP: [192.*.*.*]

InternetOpenUrlを使った例。の方ではHTMLソース?
を取得してTMemoに表示されました!!

この取得されたデータを(画像データなんですけど)自分のPCのローカルに
保存(名前をつけて保存)ってできますか?

編集    削除
にしの  2003-12-01 23:48:14  No: 5777  IP: [192.*.*.*]

InternetOpenUrlであれば、TMemoryStreamなりTFileStreamなりを用意して、

str := str + Copy(lpBuffer, 0, dwBytesRead - 1);

でコピーしているlpBuffer内のdwBytesRead分を、Stream.Write(lpBuffer[0], dwBytesRead);してやればよろしいかと思います。

Seekでうまく行きませんか?
Stream.Position :=0でも駄目ですかね。

編集    削除
のり  2003-12-01 23:55:06  No: 5778  IP: [192.*.*.*]

>Seekでうまく行きませんか?
>Stream.Position :=0でも駄目ですかね。
 でもうまくいかないです^^;

InterNetOpenUrlの方ではTMemoに表示されているので、こちらでやろうと思います。
>TMemoryStreamなりTFileStreamなりを用意して、
>str := str + Copy(lpBuffer, 0, dwBytesRead - 1);
TMemoryStream?TFileStream?  ^^;
わかりました、勉強して見ます!!

編集    削除
のり  2003-12-04 18:21:43  No: 5779  IP: [192.*.*.*]

>Seekでうまく行きませんか?
>Stream.Position :=0でも駄目ですかね。

  の部分はうまくいってたみたいです!!

  エラーが出てるのは、Memo1.Lines.LoadFromStream(Stream);
の部分で、LoadFromStreamというのがないみたいです^^;
たぶんなんですが^^;

編集    削除
のり  2003-12-04 18:34:18  No: 5780  IP: [192.*.*.*]

だんだん、てんぱってきました^^;

EIdSocketError  1行づつコメントアウトでどこまで行くかやっていたら
> IdHTTP1.Get('http://www.yahoo.co.jp/', Stream);
でエラーが出てました^^;
EIdSocketError  というの何ですが、ヘルプを見てもわかりません、教えてください;;

編集    削除
のり  2003-12-05 00:43:47  No: 5781  IP: [192.*.*.*]

できましたぁぁ!!

にしのさん、ながながとありがとうございました!!

 IdHTTP1.Get('http://www.yahoo.co.jp/', Stream);

                        ↓

 IdHTTP1.Get('http://www.yahoo.co.jp/index.html', Stream);

に変更したらいきましたw

編集    削除