delphi&C++ 將紋理保存到bmpwe

Delphi

function GetRed(color: Word): Byte;
begin
  Result := (color shr 8) and $ff;
end;

function GetGreen(color: Word): Byte;
begin
  Result := (color shr 3) and $ff;
end;

function GetBlue(color: Word): Byte;
begin
  Result := (color and $1f) shl 3;
end;

function  saveToFile(filename: string; lpSurface: TDirectDrawSurface):Boolean;
var
  lpBuffer: ^Word;                                     // 表面指針
    nPitch: Integer;                                     // 表面跨距
    nWidth, nHeight: Integer;                            // 表面寬高
  ddsd: TDDSurfaceDesc;      //DDSURFACEDESC ddsd     // 鎖定表面
  FileHeader: TBitmapFileHeader;  // BITMAPFILEHEADER  // 保存文件頭
  Header: TBitmapInfoHeader;                           // 保存文件信息
  I,J: Integer;
  WordColor: Word;
  DesMap, TempMap: ^Byte;
  Handle: Integer;
begin
  ddsd.dwSize := sizeof(ddsd);
  try
    lpSurface.Lock(ddsd);

    lpBuffer := ddsd.lpSurface;

    if lpBuffer = nil then Exit;
    nWidth := ddsd.dwWidth;
    nHeight := ddsd.dwHeight;
    nPitch := ddsd.lPitch shr 1;                        //lPitch以Byte爲單位,GraphPitch以WORD爲單位。所以GraphPitch = lPitch / 2;
    Handle := CreateFile('C:\Users\moon\Desktop\Surfacebitmap.bmp', GENERIC_READ or GENERIC_WRITE,
                          FILE_SHARE_WRITE,nil,CREATE_ALWAYS,FILE_FLAG_WRITE_THROUGH,GENERIC_READ);
    // Handle :=  FileOpen(filename,fmCreate);
    if Handle < 0 then Exit;

    FileHeader.bfType := $4D42;
    FileHeader.bfSize :=  Cardinal(nWidth * nHeight * 3 + $36);
    FileHeader.bfReserved1 := 0;
    FileHeader.bfReserved2 := 0;
    FileHeader.bfOffBits := $36;
    FileWrite(Handle ,FileHeader,sizeof(TBitmapFileHeader));   //fwrite(&FileHeader, sizeof(TBitmapFileHeader), 1, fp);

    // 填充保存的文件信息
    Header.biSize := sizeof(TBitmapInfoHeader);   // 結構的大小
    Header.biWidth := nWidth;                     // 寬
    Header.biHeight := nHeight;                   // 高
    Header.biPlanes := 1;                         // 固定
    Header.biBitCount := 24;                      // 顏色數
    Header.biCompression := BI_RGB;               // 是否壓縮
    Header.biSizeImage := nWidth * nHeight * 3;   // 圖片的大小
    Header.biXPelsPerMeter := 0;
    Header.biYPelsPerMeter := 0;
    Header.biClrUsed := 0;
    Header.biClrImportant := 0;
    FileWrite(Handle,Header, Header.biSize);            //fwrite(&Header, Header.biSize, 1, fp);

    // 寫入具體內容(從下向上存放)
    DesMap := GetMemory(Header.biSizeImage);
    TempMap := DesMap;
    Fileseek(Handle, 1, $36);
    Inc(lpBuffer,nWidth * (nHeight - 1));

    for I := 0 to nHeight - 1 do
    begin
      for J := 0 to nWidth - 1 do
      begin
        WordColor := lpBuffer^;
        TempMap^ := Byte(GetBlue(WordColor));              //  fputc(GetBlue(word), fp);         // 藍
        Inc(TempMap);
        TempMap^ := Byte(GetGreen(WordColor));             //  fputc(GetGreen(word), fp);        // 綠
        Inc(TempMap);
        TempMap^ := Byte(GetRed(WordColor));               //  fputc(GetRed(word), fp);          // 紅
        Inc(TempMap);
        Inc(lpBuffer);
      end;
      Dec(lpBuffer,nPitch * 2);                                              // 指針轉到上一行的開始
    end;

    FileWrite(Handle, DesMap^,sizeof(TBitmapInfoHeader) + sizeof(TBitmapFileHeader) + Header.biSizeImage);
    Dispose(DesMap);
    FileClose(Handle);
  finally
    lpSurface.Unlock();
  end;                                                      // 解鎖表面
end;
 

C++

 

bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
{
    WORD* lpBuffer; // 表面指針
    int nPitch; // 表面跨距
    int nWidth, nHeight; // 表面寬高

    // 打開文件s
    FILE* fp;
    if ((fp = fopen(filename, "wb ")) != NULL)
    {
        // 鎖定表面
        DDSURFACEDESC ddsd;
        ddsd.dwSize = sizeof(ddsd);
        HRESULT ddrval = lpSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
        if (ddrval == DD_OK)
        {
            lpBuffer = (WORD *)ddsd.lpSurface;
            nWidth = ddsd.dwWidth;
            nHeight = ddsd.dwHeight;
            nPitch = ddsd.lPitch > > 1; //lPitch以Byte爲單位,GraphPitch以WORD爲單位。所以GraphPitch = lPitch / 2;
        }

        // 保存文件頭
        BITMAPFILEHEADER FileHeader;
        FileHeader.bfType = 'BM ';
        FileHeader.bfSize = nWidth * nHeight * 3 + 0x36;
        FileHeader.bfReserved1 = 0;
        FileHeader.bfReserved2 = 0;
        FileHeader.bfOffBits = 0x36;
        fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);

        // 保存文件信息
        BITMAPINFOHEADER Header;
        Header.biSize = sizeof(BITMAPINFOHEADER); // 結構的大小
        Header.biWidth = nWidth; // 寬
        Header.biHeight = nHeight; // 高
        Header.biPlanes = 1; // 固定
        Header.biBitCount = 24; // 顏色數
        Header.biCompression = BI_RGB; // 是否壓縮
        Header.biSizeImage = nWidth * nHeight * 3; // 圖片的大小
        Header.biXPelsPerMeter = 0;
        Header.biYPelsPerMeter = 0;
        Header.biClrUsed = 0;
        Header.biClrImportant = 0;
        fwrite(&Header, Header.biSize, 1, fp);

        // 寫入具體內容(從下向上存放)
        fseek(fp, 0x36, SEEK_SET);
        WORD word;
        lpBuffer += nWidth * (nHeight - 1);
        for (int i = 0; i <nHeight; i++)
        {
            for (int j = 0; j <nWidth; j++)
            {
                word = *lpBuffer;
                fputc(GetBlue(word), fp); // 藍
                fputc(GetGreen(word), fp); // 綠
                fputc(GetRed(word), fp); // 紅
                lpBuffer++;
            }
            lpBuffer -= nPitch * 2; // 指針轉到上一行的開始
        }

        fclose(fp);

        // 解鎖表面
        ddrval = lpSurface->Unlock(NULL);
        return true;
    }

    return false;
}

inline unsigned char GetRed(WORD color)
{
    if (Is555)
        return (color> > 7) & 0xff;
    else
        return (color> > 8) & 0xff;
}

inline unsigned char GetGreen(WORD color)
{
    if (Is555)
        return (color> > 2) & 0xff;
    else
        return (color> > 3) & 0xff;
}

inline unsigned char GetBlue(WORD color)
{
    return (color & 0x1f) < < 3;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章