他の画像形式への対応について
furafura  2015/01/20(Tue) 19:35
実はこのような記事を知りました。
http://nilposoft.info/archives/579
現時点で信憑性は不明です。(他の記事等を観ると、エンコーダの事を表現している可能性もありそうなので)

Siv3Dで、WICによるPNGデコード処理を行ってみたい場合、現在提供の機能で、努力すれば可能かどうか教えて頂けますでしょうか?

Imageのデータが厳密にはどうなっているのか、分かりかねるので、手が出せない状態です。
CustomImageに目を付けているのですが、間違っているでしょうか?

また、WICのデコードが有用だった場合、将来的にSiv3Dで対応する可能性はありますでしょうか?
記事編集
Reputeless  2015/01/23(Fri) 16:00
image.data() で画像のピクセルの配列の先頭ポインタを取得できます。
そこへ WIC によるデコードの結果を出力すれば画像が得られます。

配列は、要素が Color 型, 要素数 width × height 個がメモリ上で連続して格納されています。
並び方は画像の左上のピクセルから右へ下へ行く方向です。

Siv3D January 2015 までは、PNG の変換には libpng, JPEG の変換には libjpeg-turbo を使用していますが、
将来のバージョンで WIC と速度を比較し、パフォーマンス改善につながるようであれば採用したいと思います。
編集
furafura  2015/01/23(Fri) 17:57
お忙しい中回答下さいましてありがとうございました。

速度面で、どの程度効果を感じられるものかは分かりません。
極端に大きな画像でなければ、優勢順位が高い問題ではないと捉えております。

画像形式については、WICコーデックはカメラメーカーが提供している場合があり、その出力結果には興味はありますが。

私の場合、極端に大きな画像を扱う場合が出てきたので、試してみたかったという所です。それで駄目なら画質を落として対処する方向です。

いただいた回答を参考にさせていただきます。
編集
furafura  2015/01/25(Sun) 18:50
誰も喜ばないと思いますが、実験コードを出しておく事にしました。
http://tanayalog.blogspot.jp/2013/12/windows-2.html
https://msdn.microsoft.com/ja-jp/library/ee719797(en-us,VS.85).aspx
等を参考にさせていただきました。丸バクリ。

パラメータ等いじっておりますが、稼働上はおそらく問題ないとは思います。
試した結論としては、非力な低速環境では、体感上で厳密なものではありませんが、速くなった感じはないに等しいと思います。

画像判定+復号+変換をWICに依存し、Imageに放り込み、Texture化しております。
実際には使う場合にはTextureの表示を行う事でしょうが、実験コードという事で。

私の場合、PNGだけ対象ですが、WIC対応画像形式ならこれで表示可能と思われます。
中・高速環境ではほとんど試しておりません。

問題画像は1枚が4608*3456のRGBの背景用PNGでありまして、大きなものですと32MBにもなる超大物。可逆圧縮であるという条件からPNGを採用。
今回の実験結果から考えて、ファイルの読み込み速度の影響が最も大きいように思います。3-4秒ぐらいかかっております。

他の画像形式については、jp2とtiff以外このコードでは検証しておりません。
Siv3D対応の可逆圧縮では、PNGより小さくなるものだとjp2やwebpがあるのですが、問題画像ともなりますと、復号に大変な時間がかかります。
WICの導入は有用な場合もあるかも知れませんが、このコードで高速化の余地が無ければ私にはあまり意味がないです。
高速化目的以外ではもう少し遊べるとは思いますが、画質を落とす等の対処を検討します。

#include <wincodec.h> // Windows Imaging Component。windowscodecs.lib もリンクが必要。
HRESULT GetPixelsFromImageFileWithConversionTo32bppRGBA(LPCWSTR imageFileName)
{
IWICImagingFactory *pFactory = NULL; // ファクトリ。デコーダを生成。
IWICBitmapDecoder *pDecoder = NULL; // デコーダ。画像ファイルからのフレーム取得に使用。
IWICBitmapFrameDecode *pFrame = NULL; // フレーム。画像一枚を格納。
IWICFormatConverter *pConverter = NULL; // コンバータ。目的のフォーマットに変換。
UINT puiWidth, puiHeight;

HRESULT hr = S_OK;
if(SUCCEEDED(hr))
{
// ファクトリの生成。
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&pFactory
);
}
if(SUCCEEDED(hr))
{
// デコーダの生成。ファイル名からデコーダを判別して生成。
hr = pFactory->CreateDecoderFromFilename(
imageFileName,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
//System::Update();
if(SUCCEEDED(hr))
{
// 一枚目のフレームを取得。
hr = pDecoder->GetFrame(0, &pFrame);
}
if(SUCCEEDED(hr))
{
// コンバータの生成。ファイル名からデコーダを判別して生成。
hr = pFactory->CreateFormatConverter(&pConverter);
}
if(SUCCEEDED(hr))
{
// コンバータの初期化。
hr = pConverter->Initialize(
pFrame,
GUID_WICPixelFormat32bppRGBA, // フォーマット指定
WICBitmapDitherTypeNone, // ディザリング指定
NULL, // パレット指定
0.f, // α スレッショルド
WICBitmapPaletteTypeCustom//WICBitmapPaletteTypeMedianCut // パレットトランスレーション
);
}
if(SUCCEEDED(hr))
{
// 画像の幅、高さを取得。
hr = pConverter->GetSize(&puiWidth, &puiHeight);
}
if(SUCCEEDED(hr))
{
Image img(puiWidth, puiHeight);
// 画素を取得。
hr = pConverter->CopyPixels(NULL, (puiWidth * 4), (puiWidth * puiHeight * 4), (LPBYTE)img.data());
Texture tx(img);
if(tx) {
ScreenTexture = tx;
}
}
// ファクトリ、デコーダ、フレームの解放。
if(pFactory)
{
pFactory->Release();
}
if(pDecoder)
{
pDecoder->Release();
}
if(pFrame)
{
pFrame->Release();
}
if(pConverter)
{
pConverter->Release();
}
return hr;
}
編集
Reputeless  2015/01/27(Tue) 00:21
コードのご提供ありがとうございます。
実装の参考にさせて頂きます。
編集
furafura  2015/01/27(Tue) 01:08
今格闘中なのですが、そのコード、どうもメモリリーク起こす感じです。
繰り返し呼び出すと、プライベートワーキングセットが増えっぱなしになり、いずれImage内部でメモリ確保出来ずに例外が発生します。
理由は分かりませんが、imgかtxが何らかの原因で解放されないようです。
WICが絡むのか、デコーダプラグインの問題かどちらかでしょうが……。

http://homepage1.nifty.com/toro/slplugin.html
がより参考になるかも知れません。
Susieとかには興味はないのですが、利用者も多いのでより安全なコードかと考えております。
編集
furafura  2015/01/28(Wed) 17:49
メモリリークしていた箇所、愚かなのですぐ分かりませんでした。
コンバータの初期化を行うとリークする事までは掴んでいたのですが、早い話がサンプルコード丸パクリが悪かったのです。元がpConvererの解放がされてなかったのでした。(上記コードは修正済み)

WICでのサポート画像対象をMSによるコーデック限定+カメラRAW無視とする場合、現行のSiv3Dとほぼ同等となり意味が乏しくなる可能性があります。
WICはサードパーティ製に上書きされて別のデコーダになりうるので、その辺りも考えると注意が必要なのかも知れません。

未確認ですがAMDがjpegデコードをGPUにやらせて高速化する話もあるらしく、WICは将来有用なものになるのかも知れません。
編集
件名
Re: 他の画像形式への対応について
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -