0

2016 年 3 月 24 日、私は 76 歳で、それを書いたときは理にかなっていると思いましたが、他のみんなと同じように、何を求めていたのかわかりません。これは、私がインターネットを精査してまとめたものです (あまりきれいではありません)。ほとんど機能しますが、欠けているのはアスペクト比を維持することだけです。背の高い写真が太って見えるようになっています。40 年間のプログラミングで、グラフィックスのコーディングに合計 2 時間費やしたことになるでしょう。:)

procedure TfrmTools.Shrink(aFn : String; Wid,Ht : Integer);
var
  Bmp : TBitmap;    // These three are created
  Jpg : TJpegImage; //  and Freed globally
  Dst : TBitmap32;  //  to save some bit-thrashing
begin
  try
    Src.Bitmap.LoadFromFile(aFn);  // Src = TImage32
    Dst:=TBitmap32.Create;
    Dst.SetSize(Wid,Ht);
    Src.Bitmap.DrawTo(Dst,Dst.BoundsRect);
    bmp:=TBitmap.Create;
    jpg:=TJPEGImage.Create;
    bmp.Assign(Dst);
    jpg.Assign(bmp);
    jpg.SaveToFile('D:\Test1280x720.jpg');  // Just testing
  finally
    Bmp.Free;  // As above
    Jpg.Free;  // As above
    Dst.Free;  // As above
  end;
end;

2016 年 3 月 23 日、私はここで善良な魂からのアドバイスを受けて、Graphis32 で弾丸をかみ砕きました。満足していましたが、壁にぶつかりました。データベースに約1200枚の画像へのパスがあり、表示、保存などはすべてうまくいっています.

一部の画像は 6 ~ 9 MB であり、PC 画面でのみ表示されるため、それほど大きく保存する必要はありません。それらを希望のサイズ、たとえば 1920 x 1080 に縮小し、H x W の比率を維持したいと考えています。すでに 1920 x 1080 より小さい画像を縮小したくありません。

私は多くの検索と試行錯誤を行ってきましたが、これまでのところエラーのみです。ユーザーが手動で作業しているときに、スケーリングや回転の後に保存部分があります。しかし、データベース全体をスキャンして、その場でサイズを変更できるようにしたいと考えています。

コードスニペットは素晴らしいでしょう。

4

2 に答える 2

1

3/24/2016この回答は、大きな画像のサイズを変更するときに残っている問題はアスペクト比がないことであるとあなたが言った場所にマークされた編集に基づいています。2 つの引数Wid, Ht: integerが適用する最大の幅と高さであると仮定すると、コメントでマークされた次の変更を提案します。

procedure TfrmTools.Shrink(aFn : String; Wid,Ht : Integer);
var
  Bmp : TBitmap;    // These three are created
  Jpg : TJpegImage; //  and Freed globally
  Dst : TBitmap32;  //  to save some bit-thrashing
  DstWidth, DstHeight: integer; // Add
  AspRatio: single;             // Add
begin
  Bmp := nil;  // not related to your question, see comment in text
  Jpg := nil;  // -"-
  Dst := nil;  // -"-
  try
    Src.Bitmap.LoadFromFile(aFn);  // Src = TImage32

  // Add following lines
  DstWidth := Src.Width;
  DstHeight := Src.Height;
  AspRatio := Src.Width/Src.Height;

  if (DstWidth > Wid) then
  begin
    DstWidth := Wid;
    DstHeight := round(DstWidth / AspRatio);
  end;

  if (DstHeight > Ht) then
  begin
    DstHeight := Ht;
    DstWidth := round(DstHeight * AspRatio);
  end;
  // end of added lines

    Dst:=TBitmap32.Create;
//    Dst.SetSize(Wid,Ht); // Replace parameters
    Dst.SetSize(DstWidth,DstHeight);
    Src.Bitmap.DrawTo(Dst,Dst.BoundsRect);
    bmp:=TBitmap.Create;
    jpg:=TJPEGImage.Create;
    bmp.Assign(Dst);
    jpg.Assign(bmp);
    jpg.SaveToFile('D:\Test1280x720.jpg');  // Just testing
  finally
    Bmp.Free;  // As above
    Jpg.Free;  // As above
    Dst.Free;  // As above
  end;
end;

BmpJpgおよび変数は、初期化されていないメモリ参照での最終的な呼び出しを防ぐために、Dst事前に nill する必要があります。これは、3 つのオブジェクトすべてが作成される前にコードで例外が発生した場合に発生する可能性があります。tryFree

于 2016-03-25T07:28:36.393 に答える
1

ファイル名のリストを繰り返し処理し、それぞれに対してサイズ変更コードを実行するだけです。簡単なスタートとして...

function TForm1.ResizeImage(const Filename: String): String;
begin
  Result:= '';
  try

    //Your resizing code here

  except
    on e: Exception do begin
      Result:= e.Message;
    end;
  end;
end;

procedure TForm1.ResizeAllImages(const List: TStringList);
var
  X: Integer;
  R: String;
begin
  for X := 0 to List.Count - 1 do begin
    R:= ResizeImage(List[X]);
    if R <> '' then begin
      //Report error in a memo control
      Memo1.Lines.Add(List[X]);
      Memo1.Lines.Add(R);
      Memo1.Lines.Add('');
    end;
  end;
end;

ファイル名のリストを にロードし、この文字列リストを渡してTStringList呼び出します。ResizeAllImages例外も報告するのは良い考えなので、非常に単純なエラー報告も含めました。ただし、たとえば進行状況バーを実装するなど、これを拡張したいことは間違いありません。

これが本番環境用である場合、たとえば、配布または販売する予定のものがある場合は、そのようなタスクに別のスレッドを使用することを検討する必要があります。

また、念のため、既存のイメージを上書きしないことを強くお勧めします。ある種の出力ディレクトリを実装し、新しくサイズ変更された画像をそこに保存します。

于 2016-03-23T23:14:18.283 に答える