7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DelphiのFMX/VCLにおけるTBitmapのサイズの最大値

Last updated at Posted at 2022-12-09

本投稿はDelphi Advent Calendar 2022 #10 の記事です。

はじめに

Delphiでかなり大きなBitmapを扱うプログラムを書く機会をいただきました。
最新の機能で書きたいと思い,FMXを利用しようとしたら,TBitmapをSetSizeしただけでエラーで落ちてしまいました。
書いたコードは以下のようなものです。

Unit1.pas

function hoge;
var
  Bitmap:TBitmap;
begin
  Bitmap:=TBitmap.Create;
  Bitmap.SetSize(10000,10000);

  ・・・・・
  Bitmap.Free;
end;

この関数を実行すると,以下のようなエラーが出ます。
Snap0002.png
そこで,FMXとVCLの32bitおよび64bitのアプリケーションでTBitmapを使用した際のTBitmapのサイズの制限を調べてみることにしました。

VCLのTBitmap

VCLの TBitmap には PixelFormat というプロパティがあります。
TPixelFormat.pf24bitTPixelFormat.pf32bit について調査しました。
TPixelFormat.pf24bitは1ピクセル当たり3byte,TPixelFormat.pf32bitは4byteで,アルファ情報を持つことができます。
1つのBitmapが利用する画素数(縦の画素 X 横の画素)にこのバイト数をかけたものにBitmapのヘッダサイズを足したものがBitmapが利用するメモリ量になります。

32bit VCLアプリケーション

32bitアプリケーションの最大メモリサイズは2GBですので。一度に使えるメモリはこれ以下になります。Bitmap以外のメモリの使用量が十分小さければ,1GBを超えるBitmapを利用できました。ただし,同時に多くのBitmapを利用する際には,その合計のメモリ量がアプリケーションの使えるメモリ量を超えないようにすることが必要です。

64bit VCLアプリケーション

64bitアプリケーションでは,1つのBitmapが利用できる最大メモリ量は2GBでした。複数のBitmapを同時に使ってもその制限は変わりませんでした。
しかし,今度はパソコンの空きメモリにより制限されます。空きメモリがメモリ全体の20%くらいまでBitmapを作成することができました。

FMXのTBitmap

FMXでDirect2Dはデフォルトでは利用するモードになっています。Direct2Dを使わない場合はGDI+を使います。
これを切り替えるのに,GlobalUseDirect2D を使います。デフォルトではTrueです。FMX.Types で定義されています。
切り替えるときには,プロジェクトソースに以下のように書きます。

Project1.dpr
program Project1;

uses
  System.StartUpCopy,
  FMX.Forms,
  FMX.Types, // GlobalUseDirect2D が定義されているUnitを追加
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  GlobalUseDirect2D:=False; // Direct2Dを使わない

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Direct2Dを使う場合

Direct2Dを使う場合のBitmapの最大サイズは,ビデオカードにより決まります。
私のビデオカードではBitmapの縦・横の最大は8192pxでした。1つのBitmapの最大サイズは256MBになります。
32Bitアプリケーションだと8個が理論上の最大数になりますが,それ以上のBitmapを生成することができました。
Direct2Dを使うとGPUがその処理をするためかもしれません。64bitも同様です。

Direct2Dを使わない場合(GDI+の場合)

GDI+の場合,Bitmapの縦・横の最大は65535px($FFFF)でした。1つのBitmapの最大サイズは16GBになります。
32Bitアプリケーションの制限を超えていますが,複数のBitmapを生成できました。64Bitも同様です。

まとめ

VCLの場合メモリサイズの制限がある。

  • 32bitアプリでは1つ1GBが目安,複数利用の場合には合計で他のプログラムの使うメモリと合わせて2GBを超えないこと。
  • 64bitアプリでは1つ2GB。複数同時利用の場合は空きメモリにより変化する。

FMXの場合縦横サイズの制限がある。

  • Direct2Dを使う場合,8192px。ただしビデオカードによりこのサイズは変動する。複数同時利用しても変化なし。
  • GDI+を使う場合,65535px。複数同時利用しても変化なし。

謝辞(引用元および参考文献)

以下のリンクが参考になりました。

貴重な情報を提供してくださった皆様,ありがとうございます。感謝します。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?