D3DXSaveSurfaceToFileで保存された画像は、Photoshopやペイントではないが開きます

StackOverflow https://stackoverflow.com/questions/2473549

  •  20-09-2019
  •  | 
  •  

質問

私はPNG、BMPやJPGファイルに、ウィンドウのDirect3D 9の表面を保存するためにD3DXSaveSurfaceToFileを使用しています。 WindowsフォトビューアーやペイントでD3DXSaveSurfaceToFileコールと、すべてのファイルのオープン罰金から返されたエラーはありません。しかし、彼らは、そのようなペイントショッププロやPhotoshopなどのハイエンドの画像編集プログラムで開きません。これらのプログラムからのエラーメッセージは、基本的には、ファイルが破損していると言います。私はペイントでファイルを開き、別のファイル名と同じファイル形式で保存する場合は、それらが他のプログラムで罰金開きます。

このはD3DXSaveSurfaceToFileは、これらのファイル形式の非標準のバージョンを書いていると信じて私をリードしています。私はペイントでファイルを再保存する中間段階なしにPhotoshopのようなプログラムで開くことができるファイルを書き出すために、この機能を得ることができ、いくつかの方法はありますか?それとも私はそれが画像?

にDirect3Dの表面を保存するのより良い仕事をして使用する必要があります別の関数があります
役に立ちましたか?

解決 3

それは私のコードのバグの組み合わせであり、それは、ファイルを読み込むことになるとPhotoshopのより寛容であることペイントことが判明しました。私のコードのバグは、ファイルが間違った拡張子(すなわちImage.bmpが実際D3DXIFF_JPGを使用して保存された)と一緒に保存される原因となりました。 JPG画像が含まれているが、BMPの拡張子を持っていたファイルを開くと、Photoshopは単にファイルを失敗しました。私はそれがファイルの拡張子を無視し、単にファイルの内容をデコードするのでペイントが働いていたと思います。

<のhref =「https://stackoverflow.com/questions/2473549/images-saved-with-d3dxsavesurfacetofile-will-open-in-paint-not-photoshop/2473569#2473569」内のファイルを見ます>画像のメタビューアには、問題を確認するために私を助けます。

他のヒント

メタビューアのイメージ内のファイルを見てみましょう。それはあなたを教えてくれないか?

残念ながらD3DXSaveSurfaceToFile()は、(それも非常に遅いです)、最も安定していません。個人的に私は以下のコードのような何かをします。これは、オフスクリーンバッファにそれを取得し、その後、スクリーンショットを撮るためにレンダリングすることにより、アンチエイリアスのディスプレイ上でも動作します。また、唯一のピクセルフォーマットの最も一般的なサポートしています。それにエラーのために申し訳ありませんが、私が働いていたアプリからそれを引っ張っています。

あなたは、その後、あなたのコードでは、おそらく別のスレッドでは、その後、あなたは異なるコードのさまざまな方法を使って好きなものに「ビットマップ」と述べ変換することができます。

void HandleScreenshot(IDirect3DDevice9* device)
{
    DWORD tcHandleScreenshot = GetTickCount();
    LPDIRECT3DSURFACE9 pd3dsBack = NULL;
    LPDIRECT3DSURFACE9 pd3dsTemp = NULL;

    // Grab the back buffer into a surface
    if ( SUCCEEDED ( device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pd3dsBack) ))
    {
        D3DSURFACE_DESC desc;
        pd3dsBack->GetDesc(&desc);

        LPDIRECT3DSURFACE9 pd3dsCopy = NULL;
        if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
        {
            if (SUCCEEDED(device->CreateRenderTarget(desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pd3dsCopy, NULL)))
            {
                if (SUCCEEDED(device->StretchRect(pd3dsBack, NULL, pd3dsCopy, NULL, D3DTEXF_NONE)))
                {
                    pd3dsBack->Release();
                    pd3dsBack = pd3dsCopy;
                }
                else
                {
                    pd3dsCopy->Release();
                }
            }
        }

        if (SUCCEEDED(device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pd3dsTemp, NULL)))
        {
            DWORD tmpTimeGRTD = GetTickCount();
            if (SUCCEEDED(device->GetRenderTargetData(pd3dsBack, pd3dsTemp)))
            {
                D3DLOCKED_RECT lockedSrcRect;
                if (SUCCEEDED(pd3dsTemp->LockRect(&lockedSrcRect, NULL, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE)))
                {

                    int nSize = desc.Width * desc.Height * 3;
                    BYTE* pixels = new BYTE[nSize +1];
                    int iSrcPitch = lockedSrcRect.Pitch;
                    BYTE* pSrcRow = (BYTE*)lockedSrcRect.pBits;

                    LPBYTE lpDest = pixels;
                    LPDWORD lpSrc;

                    switch (desc.Format)
                    {
                    case D3DFMT_A8R8G8B8:
                    case D3DFMT_X8R8G8B8:
                        for (int y = desc.Height - 1; y >= 0; y--)
                        {
                            lpSrc = reinterpret_cast<LPDWORD>(lockedSrcRect.pBits) + y * desc.Width;
                            for (unsigned int x = 0; x < desc.Width; x++)
                            {
                                *reinterpret_cast<LPDWORD>(lpDest) = *lpSrc;
                                lpSrc++;        // increment source pointer by 1 DWORD
                                lpDest += 3;    // increment destination pointer by 3 bytes
                            }
                        }
                        break;
                    default:
                        ZeroMemory(pixels, nSize);
                    }

                    pd3dsTemp->UnlockRect();

                    BITMAPINFOHEADER header;
                    header.biWidth = desc.Width; 
                    header.biHeight = desc.Height; 
                    header.biSizeImage = nSize; 
                    header.biSize = sizeof(BITMAPINFOHEADER); 
                    header.biPlanes = 1;
                    header.biBitCount =  3 * 8; // RGB 
                    header.biCompression = 0; 
                    header.biXPelsPerMeter = 0; 
                    header.biYPelsPerMeter = 0; 
                    header.biClrUsed = 0; 
                    header.biClrImportant = 0; 

                    BITMAPFILEHEADER bfh = {0};
                    bfh.bfType = 0x4d42;
                    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
                    bfh.bfSize = bfh.bfOffBits + nSize;

                    unsigned int rough_size = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + nSize;
                    unsigned char* p = new unsigned char[rough_size]

                    memcpy(p, &bfh, sizeof(BITMAPFILEHEADER));
                    p += sizeof(BITMAPFILEHEADER);
                    memcpy(p, &header, sizeof(BITMAPINFOHEADER));
                    p += sizeof(BITMAPINFOHEADER);
                    memcpy(p, pixels, nSize);

                    delete [] pixels;

                    /**********************************************/
                    // p now has a full BMP file, write it out here
                }
            }
            pd3dsTemp->Release();
        }
        pd3dsBack->Release();
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top