11

これが問題です。通常のjpgファイルとして512x512ピクセルのJPEGタイルの大規模なセットがあります。

私は多くのことを行い、最後にそれらすべてのファイルを 1 つの巨大な JPEG にステッチする必要があるソフトウェアを作成しました。

まず第一に、これを行うために ImageMagick を使用したくありませんが、ソフトウェア内で実行します。

Delphi では、JPG ファイルを別の JPG キャンバスにコピーすることはできないため、最初に TBitmap を作成する必要があります。次に、タイルを TBitmap キャンバスにコピーし、次に TBitmap を jpeg 画像に変換してファイルに保存します。

この問題は、結果のファイル サイズが大きすぎる場合に発生します (20 000 x 20 000 ピクセルなど)。TBitmap.SetSize を呼び出すと、自然にエラーが発生します (メモリ不足など)。

まったく同じマシンで Photoshop を使用していくつかのテストを行い、複雑な (空白ではない) 30 000 x 30 000 ファイルを作成して JPEG に保存することができました。

問題は、どうすれば同じことを実行できるかということです。結果をディスクに直接書き込むか、他のトリックを使用して、これらすべての JPEG をステッチする方法を見つけますか?...

20k x 20k ピクセルは十分に大きいように見えますが、この値は私のマシン (4 GB RAM) にのみ適用されるため、RAM の量が少ないとソフトウェアがさらに制限されます。

ありがとう

編集:明確にするために:

私が望むのは、これらの小さな JPG 画像をつなぎ合わせて、大きな画像を RAM に保持せずに大きな画像を書き込む方法を見つけることです。どうやらビットマップ ストリームの読み取り/書き込みはディスク上で直接可能ですが (確かではありません)、非常に大きなファイルになります。したがって、JPG 形式でこれができない場合は、TIFF や PNG などの他の圧縮形式で行うことができます。また、(すでに圧縮された) 初期の JPG 品質を失わないように、過度の再圧縮を避けたいと考えています。

したがって、完璧な解決策は、小さなファイルを直接読み取り、何らかの形で大きなファイルに書き込む方法です。タイルのサイズは 256x256 または 512x512 で、JPEG 圧縮の調整に役立ちます。

4

8 に答える 8

8

みんなありがとう !

実際、答えと考えられる解決策は、Photoshop と同じように進めることです。つまり、タイルからディスク上の大きな bmp ファイルにビットマップ ストリームを書き込み (たとえば、20 000 x 30 000 ファイルは 2.4 Gb になります)、次に、 NativeJpg ライブラリは、ビットマップ データをストライプごとにフィードすることで、この大きなビットマップを jpg に変換します。それぞれの高さは 8 ピクセルです。

また、1 行のタイル (高さ 512 ピクセル) をステッチし、それを 8 つずつ NativeJpg ライブラリにフィードしてから、次のタイル行に移動することもできます。

Erik Turner によるいくつかのサンプル コード:

procedure GetBitmapTile(BM: TBitmap; Y, X: Integer);
var JpegImage: TJpegImage;
begin
  JpegImage := NIL; // Replace with tile lookup //
  BM.PixelFormat := pf32bit;
  BM.Width := JpegImage.Width;
  BM.Height := JpegImage.Height;
  BM.Canvas.Draw(0, 0, JpegImage);
end;

procedure WriteBitmapFile(TileCountY, TileCountX: Integer; BM_Stm: TStream);
var
  BM: TBitmap;
  TileY: Integer;
  TileX: Integer;
  PixelY: Integer;
begin
  BM := TBitmap.Create;
  for TileY := 0 to TileCountY-1 do
    for TileX := 0 to TileCountX-1 do
    begin
      GetBitmapTile(BM, TileY, TileX);
      for PixelY := 0 to 511 do
        BM_Stm.Write(BM.ScanLine[PixelY]^, 512 * SizeOf(TRGBQuad));
    end;
    BM.Free;
end;

NativeJpg ライブラリ : http://www.simdesign.nl/nativejpg.html

于 2010-06-27T17:42:28.987 に答える
1

このような重労働の前に、私はhttp://www.graphicsmagick.org/に頼っています

http://graphics32.org/にも Pascal 単位のセットがありますが、かなり数学的で複雑ですが (そのため、私はそれらを機能させていません)、ハードワークのために構築されています。

于 2010-06-28T09:05:55.980 に答える
1

Photoshop は、他の多くのメディア指向プログラムと同様に、メイン メモリよりも大きなファイルを長時間処理するという問題に対処しなければなりませんでした。大きな写真の場合、画像の一部のみを機能させるタイリングが 1 つのテクニックです。

実際には、これは単純にカット アンド ペーストするよりも複雑です (しゃれが意図されています)。

私は Delphi プログラマーではありませんが、イメージを作成するときにメモリが不足すると、そのイメージを使用しようとしても同じことが起こらないのではないかと心配しています。

于 2010-06-27T10:45:07.660 に答える
1

これは非常に難しい分野であり、@Peter がすでに述べているように、Photoshop 関係者は1990 年からこの分野に取り組んできました。プログラミング言語に組み込まれている JPG デコード ライブラリは、RAM にイメージ全体をロード (およびアンパック) する可能性が高いため、おそらく使用できないでしょう。

これに対処する外部ライブラリを探すことをお勧めします-無料で利用できるまともなライブラリがあるかどうかはわかりませんが、そうかもしれません.

于 2010-06-27T10:50:37.133 に答える
1

これを処理するには、カスタム クラスを実装する必要がある場合があります。

ビデオ メモリでは、画像 (または画面バッファー) は線形配列です。水平方向の行は順番に格納され、各ピクセルは (y*width+x)-1 の配列オフセットに対応します。

したがって、320x200 の画像では、5,2 のピクセルは配列インデックス 5*320+2-1、つまり 1601 になります。テクスチャ、形状、照明効果などの描画などの操作を数学的に実行し、バッファをビデオ RAM に BLT します。

あなたの場合、組み込みのビットマップと画像クラスを使用して、メモリに収まる小さな画像を操作し、それらのピクセルデータを大きな配列または一連の配列にコピーできます(仮想メモリで作成できるかどうかは忘れています)バッファー > 物理 RAM のサイズ)。次に、その配列で直接動作する JPEG ライブラリ (マシンにインストールされている RAM のサイズとは無関係) を使用して、配列をライブラリにフィードし、コンテンツをディスクに保存できるようにする必要があります。LZW 圧縮は非常に単純であり、Web 上で JPEG 圧縮を手動で実装する上で多くの資料になると思います。

これに関する 1 つの注意点: 32 ビット OS を使用している場合、アドレス空間は 4GB に制限する必要があります。これを回避するために頭のてっぺんから考えることができる唯一の方法は、小さなバッファーを作成し (たとえば、一度に 1 行ずつ)、行が対応するピクセル データの部分でデータを埋めることです。ステッチする画像を保存して、画像領域全体をカバーするまでループします。

それが明確であることを願っています。幸運を!

于 2010-06-27T15:56:17.973 に答える
1

Delphi のイメージの最大サイズ(少なくとも以前のバージョンでは)は、システム メモリの量よりも Windows グラフィック ドライバに大きく依存していました。

これに関するいくつかの実験: EFG のコンピューター ラボ

于 2010-06-27T11:29:34.763 に答える
0

部分的な外部ソフトウェア/内部通話ソリューションはどうですか? IJG (Independent JPEG Group) には優れたコマンドライン ツール jpegtran があり、私はこれをビューアでロスレス回転に使用しました。独自のコード内で CreateProcess、WaitForsingleObject を使用して、独自のコードのように見せても問題はありません。リソース内に実行可能ファイルをパックして、一時的に抽出することもできます

そのため、同じ方法で使用できるjpegjoin ユーティリティ ( http://jpegclub.org/jpegtran/で検索できます) もあります。更新: このユーティリティはロスレス結合用であるため、必要なメモリ/ディスク フットプリントがはるかに小さくなります

于 2010-07-08T09:13:08.697 に答える
0

あなたの問題は、スプレッドシートについても考えさせます。もちろん、人口がまばらなだけです。いくつかのアイデアが得られるかもしれないいくつかの画像圧縮ライブラリを調べてみてください。

あなたにもできることは、他の誰かがそれをどのように行うかを見ることです. PixeLook Development Group には、画像およびデータ処理アプリケーションを作成するための Delphi 6 のコンポーネントであるPixeLook ライブラリがあります。

彼らは、大きな画像とデータ マトリックスを簡単に処理できると主張しており、スクリーンショット ページでは 5200 x 5200 の画像 (26 MB) の表示を示しており、テストも最大 220 MB の画像サイズで実行されたと述べています。

アプリケーションで直接大規模な画像処理が本当に必要な場合は、このパッケージが $50 で機能する可能性があります。近いが完全に正しくない場合 (jpeg に加わるかどうかはわかりません)、ソースを 299 ドルで購入して、その機能を確認し、拡張することを検討してください。

免責事項:私はこの会社とは何の関係もありません。

于 2010-06-27T15:45:03.393 に答える