Bitmapのディスク容量とは?

このQ&Aのポイント
  • Bitmapのディスク容量は、画素数×4 byteとなる。
  • PixelFormatがFormat32bppArgbの場合、保存時に圧縮されるため実際の容量は小さくなる。
  • 関連する検索キーワード: Bitmap, ディスク容量, 画素数, フォーマット
回答を見る
  • ベストアンサー

Bitmapのディスク容量

 以下、VBの記法で書きます。Windows10,.NETのGDI+を使用しています。  PixelFormat が Format32bppArgb のBitmapを作成し、描画処理が終わった後、Bitmap.Save(パス名)で保存します。  Bitmapは1250×1250(pixel)なので、そのディスク容量は、   1250×1250×4(byte)=6104 KB=6 MB くらいと思ってました。ところが保存してみると、60 KBくらい・・・。  読みだして表示するとちゃんと保存されてるので、これはこれであり難い事なのですが、どうして?、という質問です(^^;)。  PixelFormat が Format32bppArgb の場合は初期化時に、各pixelの(A,R,G,B) は (A,R,G,B)=(0,0,0,0)であり、例えばPictureBox の BackColor との兼ね合いで、(R,G,B)=(0,0,0)(黒)はDefaultで透過色になってるので、ディスク保存時には、pixel位置を表すIndex付きでpixel情報が圧縮されて保存されるのかしら?、などと想像したわけです。  たんに気になるので、どうなってるか知りたいだけです。ネットで検索してもBitmapの大きさは、画素数×4 byte という記事しか出てこないので・・・(^^;)。  関連する検索キーワードでも良いので、教えてもらえませんか。

質問者が選んだベストアンサー

  • ベストアンサー
  • asciiz
  • ベストアンサー率70% (6635/9402)
回答No.3

その .bmp ファイルの中身は、本当にビットマップでしょうか? 作成したファイルを、メモ帳に読み込ませてみましょう。 もちろんメモ帳で画像が表示できるわけではないのですが、ビットマップファイルの先頭2文字は「BM」であるはずなのです。 (「ペイント」アプリでbmp保存したファイルなどを見てみてください。) もしメモ帳で読み込ませた先頭が「臼NG」(※)となっていたならば、それはビットマップファイルのフォーマットではなく、PNGフォーマットの画像データです。 (※)本当は 0x89, "P", "N", "G" というデータで始まっているが、文字として表示すると化ける ファイル名とデータの中身が、一致していないのです。 (読み込む場合は、ファイル名の拡張子など気にせずて実際の画像データを見るので、読めてしまう) PNGフォーマットは、同じ色やパターンが連続している範囲が広いほど、良く圧縮できますし、展開すれば完全に元と同じ画像が得られます(可逆圧縮)。 (ちなみにJPEGは、圧縮展開すると、細い線やエッジがぼけてしまい、元の画像とは完全一致しない「非可逆圧縮」です。) >.NET TIPS 画像をファイルに保存するには? - C# - @IT >https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/020savebmp/savebmp.html Image.Saveメソッドにより、ファイル名だけ指定して保存するとき、そのデフォルトは「PNG形式」だそうです。 きちんとビットマップファイルとして保存したいなら、次のページのような使い方で >画像フォーマットを指定して保存する - .NET Tips (VB.NET,C#...) >https://dobon.net/vb/dotnet/graphics/saveimage.html ImageFormat.Bmp を指定して、.save してみましょう。

ddtddtddt
質問者

お礼

 メモ帳で開いた結果、pngでした。 >Image.Saveメソッドにより、ファイル名だけ指定して保存するとき、そのデフォルトは「PNG形式」だそうです。  ・・・ってヘルプに書いてありました。そんな仕様だったの?、とかなり意外な気持ちでした。今までもbmpに保存したと思っただけのものが、かなりあったわけだ。じっさい単純な拡張子なしのAAAなんていうファイル名でも保存できちゃったし・・・(^^;)。  PNGは可逆圧縮なので便利なデフォルトかも知れませんが、こりゃ落とし穴にもなるなぁ~と。  というのはFormat32bppArgbを利用したのは、単色描画で何回塗ったかをα値で記録し、後でα値を読みだして回数変換し、回数応じて別の画面を色分けするというコードを書いてたところでした。いったんSaveで保存したファイル(png)を読み込んで回数変換したところ、もとに戻ったのですが、ちゃんと保存FormatをBmpに指定してやり直すと、別画面は真っ青になりました(自分の変換規則では、α=255 → Blue)。  なるほど、Format32bppArgb が Format24bpprgb で保存されたわけねと、なかなか笑えました。この辺は、SaveのOver Loadに引数4つのものもあるので、それで調整できるのかも知れませんが・・・(^^;)。  長くなりましたが、色々勉強になりました。ありがとうございます。  

その他の回答 (5)

回答No.6

>圧縮形式(png)になってました。 やっぱりそうですよね~ デフォルトPNGだったはずなので (実はここ、確信がなかったのですが、さすがに60KBには、  ならんだろ^^  ってな事で圧縮形式だったことには確信はあったもので) なお、BMPにも、圧縮形式はありますが。 ほぼ使われてません。。

  • pfarm
  • ベストアンサー率51% (67/129)
回答No.5

保存したBitmapのフォーマットによって、ディスク容量が異なる場合があります。特に、保存するBitmapの圧縮方式によってディスク容量が大きく変化することがあります。 Bitmap.Saveメソッドは、第2引数で圧縮方式を指定できます。デフォルト値はImageFormat.Bmpで、この場合は非圧縮のBitmapが保存されます。一方、ImageFormat.Pngを指定すると、データが圧縮されたPNG形式で保存されます。 例えば、1250x1250のFormat32bppArgb Bitmapを保存する場合、以下のように書くことでPNG形式で保存することができます。 bmp.Save("ファイルパス", System.Drawing.Imaging.ImageFormat.Png) 保存されるディスク容量は、フォーマットや圧縮方式によって変化します。上記の方法でPNG形式で保存すると、ディスク容量は期待通りの6MB程度になる可能性が高いです。

ddtddtddt
質問者

お礼

 回答ありがとうございます。  結局、Saveで第二引数を省略するとデフォルトでpngで保存されるとわかりました(意外だった)。  詳しくは#3さんのお礼をご覧ください。思わず笑っちゃいました(^^;)。

  • sknbsknb2
  • ベストアンサー率38% (1126/2906)
回答No.4

可能性としては、下記くらいでしょうか。 (1)画像として、何らかの圧縮形式が指定されている。 (2)ストレージが、ファイル圧縮して保存する設定になっている。 (2)は、ストレージのフォーマットは多分NTFSだと思いますが、特に指定しなくても圧縮する設定にできるので、そのせいで小さくなっている可能性があります。

ddtddtddt
質問者

お礼

 回答ありがとうございます。 (1)  GDI+のデフォルトで、Bitmap.Saveメソッドはファイル名のみ指定した場合、pngで保存されると今回知りました。 (2)  そういう事もあり得るんですね。  結局(1)だったのですが、詳しくは#3さんへのお礼をご覧ください。

  • dell_OK
  • ベストアンサー率13% (740/5643)
回答No.2

Saveメソッドの第二引数が指定できますか。 Bitmap.Save(パス名, ImageFormat.Bmp)

ddtddtddt
質問者

お礼

 回答ありがとうございます。  Saveの第二引数を指定できるのは知ってましたが、省略した場合、まさか別形式で保存されるとは思ってませんでした。ヘルプを読み返してみるとDefaultでpngだよと、ちゃんと書かれていましたが、まさかなぁ~と(^^;)。  で、ちゃんとbmpで保存してみると期待通り6 MBにはなったのですが、なかなか笑える結果でした(詳しくは、#3さんへのお礼で・・・(^^))。

回答No.1

何形式でした?それ。 メモリ上がBitmapだとしても、 ファイル形式もBitmapとは限らないかと。 恐らく、圧縮形式になってると思われます。

ddtddtddt
質問者

お礼

 回答ありがとうございます。  圧縮形式(png)になってました。で、#3さんのお礼に書くように、保存Formatを指定してBitmapとして保存してみると某事情から、なかなか笑える結果となりました(^^)。

関連するQ&A

  • Rectangle(Bitmap)の幅と高さ

     以下、VBの記法で書きます。Windows10,.NETのGDI+を使用しています。  今まであまり気にしていなかったのですが、今回LockBitsとUnLockBitsを使用してBitmapのpixel情報をCopyするコードを書く事になり、急に気になり出しました。  LockBitsを使用する際、Rectangle構造体で読みだすBitmapの範囲を指定します。Rectangleが指定する実際のpixelですが、   (Rectangle.Left + Rectangle.Width - 1)×(Rectangle.Top + Rectangle.Height - 1) の範囲かな?、と思いました。例えば、   Dim Rect as Rectangle = New Rectangle(1, 1, 0, 0) などとやると、Rectは空になるし、(1, 1)一点を表すRectangleなら、   Dim Rect as Rectangle = New Rectangle(1, 1, 1, 1) なので・・・。  BitmapのWidthとHeightについても同様かと思います。実際の動作には余り影響しないのですが、気になったもので・・・。

  • 画像の容量を減らしたい!

    iBook G4を使用しています。 AppleWorksを使用して絵を描きました。 実際は36ピクセルより高さが低いんですが、36ピクセルが最小値のようで、それ以上小さくすることは不可能でした。 なので、そのままそれは保存しました。(下側に白い部分あり) 容量は8KBです。 その絵をiPhotoへ持って行き、白い部分以外を切り出して保存したところ、元々のファイル容量よりも多くなってしまいました。 できれば2KBくらいに下げたいのですが、どのようにしたらよいでしょうか?(携帯で使いたいので。) デコメ配信サイトなどでは、アニメにもかかわらず、1KBや2KBだし。。 やはりjpegではなく、gifファイルにすべきでしょうか。 またiPhotoを使わないで36ピクセルより小さい画像を作成する方法があったら教えてください。(標準ソフトで行いたいです。)

    • ベストアンサー
    • Mac
  • 画像のビット数を変更する方法

    http://okwave.jp/qa/q8880161.html このページなどで画像の取扱に関して詳しく教えていただきました。 大体、思ったことはできるようになったのですが まだ疑問点が残っております。 例えば、24bit画像をGDI+で読み込んで、 アルファチャンネルに情報を書き加えた後、 そのまま画像を出力します。 するとirfanviewなどで読み込んだ際に アルファチャンネルに情報をもっているにも拘わらず 24bit画像をとして認識されてしまいます。 アルファチャンネルをもっているかいないかではなく 画像のインデックスのところに24か32bitかを識別するものが含まれているようです。 読み込んだ24bit画像を32bit画像に変換したいのですが どのようにすれば良いでしょうか? GdipCreateBitmapFromScan0(lngWidth, lngHeight, 0, PixelFormat32bppARGB, ByVal 0&, hBmp2) を使えば、32bit画像を生成できますが 新たにbitmapオブジェクトを生成せずに 読み込んだオブジェクトのbit数を変更する方法を教えてください。

  • GDI+のDrawStringを使って文字を滑らかに描画したいのですが。。。

    GDI+のDrawStringを使って文字を滑らかに描画したいのですが。。。 環境は、VC++のWin32プロジェクトです。 WindowのデバイスコンテキストからGraphicsオブジェクトを生成し、DrawStringとすると滑らかに描画されます。 しかし、BitmapオブジェクトからGraphicsオブジェクトを生成し、DrawStringを行うとビットマップフォントのようです。 Graphics g(hdc); g.DrawString(......); -> この場合はなめらか(画像の下の方) しかし、 Bitmap bmp(w, h, PixelFormat32bppARGB); Graphics g (&bmp); g.SetSmootingMode(SmoothingModeHighQuality); g.DrawString(...); -> ジャギが目立つ。(画像の上の方) ビットマップ(メモリ)にスムーズなテキストを描画することはできないのでしょうか? ちなみにフォントはメイリオです。

  • bitmap画像の保存がうまくいきません。

    VC++のMFC、ダイアログベースで画像処理のソフトを作っています。 処理した画像を保存したいのですが、「描画できませんでした」というメッセージのでるファイルになってしまい、うまく保存できません。 プログラムは以下のようになっていてピクチャーコントロールの変数をm_pict8にしています。また、画像は24ビットで240×320のものを保存します。 static LONG CalcScanLineByte(const LONG w, const WORD bpp) { return (((bpp * w) + 31) / 32) * 4; } //----------------------------------------------------------- void Cstart2Dlg::OnBnClickedButton10() //保存ボタン { CFileDialog myDLG(FALSE,"BMP","*.BMP",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"画像(*.BMP)|*.BMP||"); if(myDLG.DoModal() == IDOK){ CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate | CFile::modeWrite|CFile::typeBinary); //ピクチャボックスからビットマップを取り出す HBITMAP hBitmap = m_pict8.GetBitmap(); //無いので処理できない if(hBitmap == NULL)return; //ビットマップの情報を取る BITMAP bitmap = {0}; ::GetObject(hBitmap, sizeof(bitmap), &bitmap); //4バイト調整したスキャンラインのサイズ const int iScanLineByte = ::CalcScanLineByte(240, bitmap.bmBitsPixel); //const int iScanLineByte = ::CalcScanLineByte(bitmap.bmWidth, bitmap.bmBitsPixel); //ファイルヘッダとビットマップヘッダ BITMAPFILEHEADER bmfh = {sizeof(bmfh)}; BITMAPINFOHEADER bmif = {sizeof(bmif)}; //ビットマップである事を示す名称 bmfh.bfType = ('M' << 8) | 'B'; //イメージデータへのオフセットはファイルヘッダ+ビットマップヘッダ bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmif); //見ての通り bmif.biBitCount = 24; //24ビットの時はBI_RGBで固定 bmif.biCompression = BI_RGB; //常に1で固定 bmif.biPlanes = 1; //見ての通り bmif.biWidth = 240; bmif.biHeight= 320; //bmif.biWidth = bitmap.bmWidth; //bmif.biHeight= bitmap.bmHeight; //4バイト調整も含めた正確な合計バイトサイズが必要 bmif.biSizeImage = iScanLineByte * bmif.biHeight; //ファイルヘッダ→ビットマップヘッダの順番に書き出す fout.Write(&bmfh, sizeof(bmfh)); fout.Write(&bmif, sizeof(bmif)); //イメージデータをセーブする HDC hMemDC = ::CreateCompatibleDC(NULL); ::SelectObject(hMemDC, hBitmap); //yを縦幅-1から回転させないと上下逆転してしまう for(int y = bmif.biHeight - 1; y >= 0; --y) { //3バイトずつステップする for(int x = 0; x < iScanLineByte; x += 3) { const COLORREF cref = ::GetPixel(hMemDC, x / 3, y); //色素の位置関係をBGRにしないと赤と青の関係が逆転してしまう const BYTE arrBy[3] = {GetBValue(cref), GetGValue(cref), GetRValue(cref)}; //1ピクセル分(3バイト)書き出す fout.Write(arrBy, sizeof(arrBy)); } } ::DeleteDC(hMemDC); } どこか改善点などありましたら、よろしくお願いいたします。

  • RoxioのDrag-To-Discで・・・

    RoxioのDrag-To-DiscでCD-Rを入れてフォーマットを しようとすると「ドライブDにあるディスクのフォーマットに失敗しました。ドライブへコマンドを転送中に 通信エラーが発生しました。」と出てフォーマット することができません。ファイルを保存しようとしても同様になってします。どうしたらよいのでしょうか・・・?

  • C# でパネルのマウスイベントが取得できない

    OpenNI(キネクトセンサー)のサンプルプログラムは、C#のパネルにbitmapを描画し続けるのですが、 描画中、そのパネルのマウスイベントが生じない(無視されている?)ようです。マウスの位置から 補助線を引いたりしたいのですが、描画中にマウスイベントが取得できる方法をご存知の方、お願いします。以下サンプルソースそのままです。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; using OpenNI; using System.Threading; using System.Drawing.Imaging; namespace SimpleViewer.net { private unsafe void ReaderThread() { DepthMetaData depthMD = new DepthMetaData(); while (this.shouldRun) { try { this.context.WaitOneUpdateAll(this.depth); } catch (Exception) { } this.depth.GetMetaData(depthMD); lock (this) { Rectangle rect = new Rectangle(0, 0, this.bitmap.Width, this.bitmap.Height); BitmapData data = this.bitmap.LockBits(rect, ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); ushort* pDepth = (ushort*)this.depth.DepthMapPtr.ToPointer(); // set pixels for (int y = 0; y < depthMD.YRes; ++y) { byte* pDest = (byte*)data.Scan0.ToPointer() + y * data.Stride; for (int x = 0; x < depthMD.XRes; ++x, ++pDepth, pDest += 3) { byte pixel = (byte)this.histogram[*pDepth]; pDest[0] = 0; pDest[1] = pixel; pDest[2] = pixel; } } this.bitmap.UnlockBits(data); } this.Invalidate(); } } private readonly string SAMPLE_XML_FILE = @"../../../Data/SamplesConfig.xml"; private Context context; private ScriptNode scriptNode; private DepthGenerator depth; private Thread readerThread; private bool shouldRun; private Bitmap bitmap; private int[] histogram; } }

  • DVDディスクのフォーマットについて

    昔の8ミリをDVDにコピーして保存を試みています。日立のDVDレコーダーをつかっているのですが、未使用のDVD-Rを入れるとフォーマットを要求され、VR形式がVF(ビデオ)形式か、選択を求められます。他のDVDと互換性の高いVFでフォーマットすると、古いDVDプレーヤーで再生可能なのですが、パソコンで読みません。VRでフォーマットするとPCで読むけれど、DVDプレーヤーでは読みません。もちろん、どちらもファイナライズしてからです。以前に、どうフォーマットしたか分からないのですが、DVD-RWで保存したものがあり、それは、DVDレコーダーでもプレーヤーでもPCでも読みます。DVD-Rでダビングしたものをファイナライズするときに、2枚、なぜかディスクが壊れました。いったい、どのディスクをどういう形式でフォーマットすると、保存、いろいろな機器での再生に一番いいのでしょうか。8ミリテープとデッキが劣化する前に30本のテープをDVDにして保存したいのですが・・・。どなたか、詳しい方、ご解説をお願い申し上げます。

  • VB.NETでのPictureBoxによる画像保存について

    またお世話になります。 VB.NETでプログラムでPictureBoxに絵を描かせているのですが、そこまでは表示させることができました。このできた画像をBitmapなりjpegなりに保存させて、ほかの画像ビューワ等でも見れる形にしたいのですがうまくいきません。 ちなみに今はこのように書いて、 Dim gra1 As Graphics = PictureBox1.CreateGraphics FileOpen(2, myfile2, OpenMode.Output) (絵を描かせるプログラム) PictureBox1.Image.Save(myfile2, System.Drawing.Imaging.ImageFormat.Bmp) FileClose(2) としてまわしたところ、 System.Runtime.InteropServices.ExternalException' のハンドルされていない例外が system.drawing.dll で発生しました。 追加情報 : GDI+ で一般的なエラーが発生しました。 といわれました。 どなたかご教授いただけたらお願いしますm(__)m

  • USBフラッシュの容量

    1年ほど使っていたUSBフラッシュメモリー1G(A DATA)ですが、 保存していたファイル等を削除してFATでフォーマットしました。 再度ファイルを入れようとしたら容量不足で入らなくなりました。 プロパティを調べたら空き容量が476KBしか無くなっていました。 ツール>ハードウェア>USB>プロパディ>ボリューム>表示で表示させると ディスク          Disk1 種類            リムーバブル 状態            オンライン パーティションのスタイル  マスタブートレート(MBR) 容量            964MB 末割り当て領域       0MB 予約済み領域        0MB ボリューム容量       0MB 容量964MBなのに、ボリューム容量が0MBとは? 隠しファイルもありませんし、再度フォーマットしても変わりませんでした。 ほかのパソコンでも容量は476KBでしたし、ほかのUSBメモリーは問題なく表示されます。 ただXPで調べた時に「FAT12でフォーマットされています」と書かれていたようですが、 真夜中の操作のため記憶がちょっと曖昧です。 最悪メモリの処分も考えていますが、直す方法はあるでしょうか。 PCはビスタで操作していました。 よろしくお願い致します。

専門家に質問してみよう