Chartの画像保存

解決


tos  2009-03-26 02:33:17  No: 33753

皆さんこんにちは。
現在、Chartの画像をファイルに保存する際、"PrintPartial"を使用して一旦プリンタで印刷し、その紙をスキャナで読み込んで画像ファイルとして保存しています。
とても面倒ですので、Chartを直接画像ファイル(*.jpeg)に保存する方法がありましたら、教えてください。


Mr.XRAY  2009-03-26 06:08:27  No: 33754

r.XRAYです.

Delphi6,7,2007,2009に附属するTeeChartには,
メタファイルまたはヒットマップとして保存するメソッドはありますが,
JPEGで保存するメソッドはありません.
チャートをメタファイルで取得するメソッドがありますから,
以下の手順で保存できると思います.

1. メタファイルを作成する
2. ビットマップのインスタンスを作成し,そのCanvasにメタファイルを描画する
3. ビットマップをJPEGに変換して保存する

どうでしょう.


Mr.XRAY  2009-03-26 18:54:49  No: 33755

>チャートをメタファイルで取得するメソッドがありますから,

Delphi2007,2009であれば,チャートをビットマップに変換する関数がありますから,
比較的簡単になりますね.


tos  2009-03-26 19:47:42  No: 33756

Mr.XRAYさん、たびたびの返信ありがとうございます。
当方の環境は、Delphi7です。

当該アプリは、MDIスタイルで子フォームには
TChartが全面に置かれています。
印刷する際は、以下のように子フォームを並べて
印刷しています。

procedure TFmMain.PrintfChart;
var
  R : TRect;
  graph_num:Integer;
  child_index:Integer;
  graph_index:Integer;
  page_height:Integer;
  capture_width:Integer;
begin

  Printer.BeginDoc;

  capture_width := 200;
  graph_index := 0;
  page_height := Printer.PageHeight - capture_width;

  for child_index := 0 to MDIChildCount - 1 do
  begin
    if IsIconic(TFmGraphDisplay(MDIChildren[child_index]).Handle) = False then
    begin
      Inc(graph_index);

      With R do
      begin
        Left  := 0;
        Right := Printer.PageWidth - 1;
        Top  :=  page_height div graph_num * (graph_index - 1) + capture_width;
        Bottom:= page_height div graph_num * graph_index - 1 + capture_width;
      end;

{*}  TFmGraphDisplay(MDIChildren[child_index]).ChGraph.PrintPartial(R);
    end;
  end;

  Printer.EndDoc;
end;

で、Mr.XRAYさんの言われたように、{*}の箇所を
以下のようにしようとしたのですが、「2. ビットマップのインスタンスを作成し,
そのCanvasにメタファイルを描画する」のところで詰まってしまいました。
  
  Chart1.SaveToMetafileRect(false, 'metafile.dat', rect);
  bit_file := TBitMap.Create;
  //ビットマップのCanvasにメタファイルを描画する???
  bit_file.Canvas  ???

ここは、どのように処理すれば良いでしょうか?


Mr.XRAY  2009-03-27 02:02:07  No: 33757

>  bit_file.Canvas  ???

この場合,StretchDrawでよろしいのではないでしょうか.

AAA.Canvas.StretchDraw(Rect(0,0,Chart1.Width,Chart1.Height),AMeta);

AAAはTBitmap
AMetaはTMetaFile

TCanvasを少しヘルプでみたほうがいいかも知れません.
では,がんばってください,


tos  2009-03-27 03:06:30  No: 33758

Mr.XRAYさん、返信ありがとうございます。
<TCanvasを少しヘルプで見たほうがいいかも知れません。
わかりました。
がんばってみます。


Mr.XRAY  2009-03-27 06:54:40  No: 33759

Mr.XRAYです.

>{*}  TFmGraphDisplay(MDIChildren[child_index]).ChGraph.PrintPartial(R);

これは,TChartがalClientで表示されているMDIの意味のようですが,
あくまでもTChartを対象としてやってみました.
以下は,ChartFormというフォームの,Chart1というチャートを,
JPEGとして保存する例です.

動作確認は,Windows XP(SP3) + Delphi7 Pro
TeeChart(TChart)はDelphi7 Pro附属のStandard版です.

TChartは,ヘルプでは,
Delphi7の場合
1. キーワードに[TChart]と入力
2. リストから[TChart]を開く
3. 検索結果から[TChartコンポーネント]を開く
4. メソッドを表示
5. 使えそうな文字があるメソッド名の説明を開いて確認してみる

ですね.
ここに,[TeeCreateMetafile]というのがあります.これを使用した例です.    

//  JPEGの使用にはusesにJPegが必要

procedure TForm1.Button3Click(Sender: TObject);
var
    AMeta   : TMetafile;
    ABmp    : TBitmap;
    AJpeg   : TJpegImage;
    AWidth  : Integer;
    AHeight : Integer;
begin
    AMeta := TMetafile.Create;
    ABmp  := TBitmap.Create;
    AJpeg := TJPEGImage.Create;
    try
      AWidth  := ChartForm.Chart1.Width;
      AHeight := ChartForm.Chart1.Height;

      //Chart1の画像をメタファイルにする
      AMeta := ChartForm.Chart1.TeeCreateMetafile(True, ChartForm.Chart1.ClientRect);
      
      //Bitmapのサイズを設定
      ABmp.Width :=AWidth;
      ABmp.Height:=AHeight;
      
      //BitmapのCanvasにAMetaを描画
      ABmp.Canvas.StretchDraw(Rect(0,0,ABmp.Width,ABmp.Height),AMeta);
      
      //Jpegに変換して保存
      AJpeg.Assign(ABmp);
      AJpeg.SaveToFile('AJpeg.jpg');
    finally
      FreeAndNil(AJpeg);
      FreeAndNil(ABmp);
      FreeAndNil(AMeta);
    end;
end;


Manbon  2009-04-01 20:01:57  No: 33760

Delphi5ですが、SaveToBitmapFileというのがありますので、
これでビットマップを作成してjpgに変換ではダメなのでしょうか?


Mr.XRAY  2009-04-01 21:50:51  No: 33761

Mr.XRAY
何か文句があるようですね(笑).

>これでビットマップを作成してjpgに変換ではダメなのでしょうか?

全く問題ないと思います.
提示のコードは,保存ファイルを作らないで,という考え方でのコードです.
これは好みの問題もあると思いますが.

「勝てば官軍,動けば正義」です(笑).
ある目的のためのコーディングというのは,1つだけとは限らないと思います.
私のサイトに置いてあるサンプルプログラム集なんかヒドイもんです.
同じ目的のためのサンプルがいくつもあります.
人心を惑わすサンプル集ですね.


Manbon  2009-04-01 22:46:35  No: 33762

そうですね。1つだけではないですよね。
ただ、Canvasを使用しないで済む方法のほうが
簡単に理解できると思いましたもので。


tos  2009-04-03 00:05:12  No: 33763

Mr.XRAYさん、返事が遅れまして、申し訳ありません。

ご推察のとおりこのアプリは、TChartがalClientで
配置されている子フォームを配置するもので、
この配置され表示している状態をプリンタに印刷していました。
(いまのところ「上下に並べて表示」しか対応できていませんが・・・)

教えていただいた方法を参考にして、以下のように実装しまして、
今のところ、「上下に並べて表示」状態だけですが、
希望通りファイルに保存することが出来るようになりました。

ありがとうございました。

procedure TFmMain.Button2Click(Sender: TObject);
var
  AMeta   : TMetafile;
  ABmp    : TBitmap;
  AJpeg   : TJpegImage;

  child_index : Integer;
  top_pos : Integer;
  one_graph_height : Integer;
begin
  AMeta := TMetafile.Create;
  ABmp  := TBitmap.Create;
  AJpeg := TJPEGImage.Create;

  try
    //Bitmapのサイズを設定
    ABmp.Width  := FmMain.ClientWidth;
    ABmp.Height := FmMain.ClientHeight;

    top_pos := 0;
    one_graph_height := Trunc(FmMain.ClientHeight / GetActiveGraphNum);
    for child_index := 0 to MDIChildCount - 1 do
    begin
      if IsIconic(TFmGraphDisplay(MDIChildren[child_index]).Handle) = False then
      begin
        //Chart1の画像をメタファイルにする
        AMeta := TFmGraphDisplay(MDIChildren[child_index]).ChGraph.TeeCreateMetafile(True,
                                                                                     TFmGraphDisplay(MDIChildren[child_index]).ChGraph.ClientRect);
        //BitmapのCanvasにAMetaを描画
        ABmp.Canvas.StretchDraw(Rect(0,top_pos,TFmGraphDisplay(MDIChildren[child_index]).Width,
                                     top_pos + TFmGraphDisplay(MDIChildren[child_index]).Height), AMeta);

        top_pos := top_pos + one_graph_height;
      end;
    end;
      //Jpegに変換して保存
      AJpeg.Assign(ABmp);
      AJpeg.SaveToFile('AJpegMy.jpg');
  finally
    FreeAndNil(AJpeg);
    FreeAndNil(ABmp);
    FreeAndNil(AMeta);
  end;
end;


Mr.XRAY  2009-04-03 08:19:24  No: 33764

tosさんこんにちは.お疲れ様です.
Mr.XRAYです.がんばってください.

>ただ、Canvasを使用しないで済む方法のほうが
>簡単に理解できると思いましたもので。

そうですね.いろいろオブジェクトを生成したりしてもいますし.
面倒な感じもしますね.

最近Vistaを少しいじっています.
VistaのUACを考えると,どうらかと言うと,なるべく外部ファイルを作らない
方向にいってしまいます.
作成したアプリがどういう状況で使用されるかにもよりますが.

アプリ起動者の権限によっては,保存か読出しができなくなる例
http://mrxray.on.coocan.jp/bbs/DelphiBBS/mrxray_delphifan_coffe.cgi?tree=s1725#1730


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加