This commit is contained in:
yangjiaxuan 2023-07-14 17:13:08 +08:00
commit 809e720ec7
4 changed files with 207 additions and 64 deletions

View File

@ -99,7 +99,11 @@ HGBase_CreateImage
HGBase_CreateImageWithData
HGBase_CreateImageFromData
HGBase_CreateImageFromHBITMAP
HGBase_CreateImageFromDIB
HGBase_CreateDIBFile
HGBase_CreateImageFromFile
HGBase_CreateDIBStream
HGBase_DestroyStream
HGBase_CreateImageFromStream
HGBase_CloneImage
HGBase_DestroyImage
HGBase_GetImageData

View File

@ -2,6 +2,7 @@
#include "HGInc.h"
#if defined(HG_CMP_MSC)
#include <combaseapi.h>
#include <atlstr.h>
#include <gdiplus.h>
#endif
@ -522,12 +523,10 @@ static HGResult LoadGdiImage(Gdiplus::Image* pImage, const HGImageRoi* roi, HGUI
return ret;
}
if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_BGRA == type)
{
HBITMAP hBmp = NULL;
HGBase_GetHBITMAPOfImage(*image, &hBmp);
assert(NULL != hBmp);
if (NULL != hBmp)
{
HDC hMem = CreateCompatibleDC(NULL);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMem, hBmp);
Gdiplus::Graphics graphics(hMem);
@ -539,8 +538,10 @@ static HGResult LoadGdiImage(Gdiplus::Image* pImage, const HGImageRoi* roi, HGUI
}
else
{
HGUInt type2 = HGBASE_IMGTYPE_BGR;
if (HGBASE_IMGTYPE_RGBA == type)
HGUInt type2 = type;
if (HGBASE_IMGTYPE_RGB == type)
type2 = HGBASE_IMGTYPE_BGR;
else if (HGBASE_IMGTYPE_RGBA == type)
type2 = HGBASE_IMGTYPE_BGRA;
HGImage image2 = NULL;
@ -565,10 +566,78 @@ static HGResult LoadGdiImage(Gdiplus::Image* pImage, const HGImageRoi* roi, HGUI
return ret;
}
HGResult HGAPI HGBase_CreateImageFromDIB(HGLOBAL hMem, const HGImageRoi* roi,
HGResult HGAPI HGBase_CreateDIBFile(HGLOBAL hMem, const HGChar *fileName)
{
if (NULL == hMem || NULL == fileName)
{
return HGBASE_ERR_INVALIDARG;
}
HGResult ret = HGBASE_ERR_FAIL;
ULONG size = (ULONG)GlobalSize(hMem);
void* pMem = GlobalLock(hMem);
if (NULL != pMem)
{
FILE *file = fopen(fileName, "wb");
if (NULL != file)
{
BITMAPINFOHEADER* infoHeader = (BITMAPINFOHEADER*)pMem;
DWORD bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
if (infoHeader->biBitCount <= 8)
bfOffBits += ((HGUInt)(1 << infoHeader->biBitCount) * sizeof(RGBQUAD));
BITMAPFILEHEADER fileHeader = { 0 };
fileHeader.bfType = 0x4D42;
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + size;
fileHeader.bfOffBits = bfOffBits;
fwrite(&fileHeader, 1, sizeof(BITMAPFILEHEADER), file);
fwrite(pMem, 1, size, file);
fclose(file);
ret = HGBASE_ERR_OK;
}
GlobalUnlock(hMem);
}
return ret;
}
HGResult HGAPI HGBase_CreateImageFromFile(const HGChar *fileName, const HGImageRoi* roi,
HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == hMem || NULL == image)
if (NULL == fileName || NULL == image)
{
return HGBASE_ERR_INVALIDARG;
}
HGResult ret = HGBASE_ERR_FAIL;
ULONG_PTR nToken = 0;
Gdiplus::GdiplusStartupInput input;
Gdiplus::GdiplusStartupOutput output;
Gdiplus::GdiplusStartup(&nToken, &input, &output);
assert(0 != nToken);
CStringW fileName2(fileName);
Gdiplus::Image *img = new Gdiplus::Image(fileName2);
Gdiplus::Status status = img->GetLastStatus();
if (Gdiplus::Ok == status)
{
ret = LoadGdiImage(img, roi, type, origin, image);
}
delete img;
Gdiplus::GdiplusShutdown(nToken);
nToken = 0;
return ret;
}
HGResult HGAPI HGBase_CreateDIBStream(HGLOBAL hMem, HGStream *stream)
{
if (NULL == hMem || NULL == stream)
{
return HGBASE_ERR_INVALIDARG;
}
@ -597,12 +666,45 @@ HGResult HGAPI HGBase_CreateImageFromDIB(HGLOBAL hMem, const HGImageRoi* roi,
pStream->Write(&fileHeader, sizeof(BITMAPFILEHEADER), &writeSize);
pStream->Write(pMem, size, &writeSize);
*stream = (HGStream)pStream;
ret = HGBASE_ERR_OK;
}
GlobalUnlock(hMem);
}
return ret;
}
HGResult HGAPI HGBase_DestroyStream(HGStream stream)
{
if (NULL == stream)
{
return HGBASE_ERR_INVALIDARG;
}
IStream* pStream = (IStream*)stream;
pStream->Release();
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_CreateImageFromStream(HGStream stream, const HGImageRoi* roi,
HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == stream || NULL == image)
{
return HGBASE_ERR_INVALIDARG;
}
HGResult ret = HGBASE_ERR_FAIL;
ULONG_PTR nToken = 0;
Gdiplus::GdiplusStartupInput input;
Gdiplus::GdiplusStartupOutput output;
Gdiplus::GdiplusStartup(&nToken, &input, &output);
assert(0 != nToken);
IStream* pStream = (IStream*)stream;
Gdiplus::Image *img = new Gdiplus::Image(pStream);
Gdiplus::Status status = img->GetLastStatus();
if (Gdiplus::Ok == status)
@ -614,12 +716,6 @@ HGResult HGAPI HGBase_CreateImageFromDIB(HGLOBAL hMem, const HGImageRoi* roi,
Gdiplus::GdiplusShutdown(nToken);
nToken = 0;
pStream->Release();
}
GlobalUnlock(hMem);
}
return ret;
}

View File

@ -8,6 +8,9 @@
#endif
HG_DECLARE_HANDLE(HGImage);
#if defined(HG_CMP_MSC)
HG_DECLARE_HANDLE(HGStream);
#endif
/* 1位黑白图 */
#define HGBASE_IMGTYPE_BINARY 1L
@ -120,11 +123,28 @@ HGEXPORT HGResult HGAPI HGBase_CreateImageFromData(HGByte* data, const HGImageIn
HGEXPORT HGResult HGAPI HGBase_CreateImageFromHBITMAP(HBITMAP hBmp, const HGImageRoi* roi,
HGUInt type, HGUInt origin, HGImage* image);
/* 从DIB内存创建新图像
/* 创建文件
*/
HGEXPORT HGResult HGAPI HGBase_CreateDIBFile(HGLOBAL hMem, const HGChar *fileName);
/* 从文件加载图像
*/
HGEXPORT HGResult HGAPI HGBase_CreateImageFromFile(const HGChar *fileName, const HGImageRoi* roi,
HGUInt type, HGUInt origin, HGImage* image);
/* 创建DIB流
*/
HGEXPORT HGResult HGAPI HGBase_CreateDIBStream(HGLOBAL hMem, HGStream *stream);
/* 销毁流
*/
HGEXPORT HGResult HGAPI HGBase_DestroyStream(HGStream stream);
/* 从流创建新图像
* :
* 1) hMem: in, DIB内存句柄
* 2) roi: DIB内存的感兴趣区域, NULL表示整个图像区域
* 3) type: in, , 0DIB内存最接近的type
* 1) stream: in,
* 2) roi: , NULL表示整个图像区域
* 3) type: in, , 0type
* 4) origin: in, ,
* 5) image: out
* :
@ -133,9 +153,9 @@ HGEXPORT HGResult HGAPI HGBase_CreateImageFromHBITMAP(HBITMAP hBmp, const HGImag
* 2) width=roi->right-roi->left; height=roi->bottom-roi->top; type=type; widthStep为4字节对齐;
* origin=origin
* 3) roi为{0, 0, width, height}
* 4) xdpi=DIB的xDPI, ydpi=DIB的yDPI
* 4) xdpi=xDPI, ydpi=yDPI
*/
HGEXPORT HGResult HGAPI HGBase_CreateImageFromDIB(HGLOBAL hMem, const HGImageRoi* roi,
HGEXPORT HGResult HGAPI HGBase_CreateImageFromStream(HGStream stream, const HGImageRoi* roi,
HGUInt type, HGUInt origin, HGImage* image);
#endif /* HG_CMP_MSC */

View File

@ -1,6 +1,7 @@
#include "HGTwainImpl.hpp"
#include "../base/HGInc.h"
#include "../base/HGInfo.h"
#include "../base/HGUtility.h"
#include "app_cfg.h"
std::map<HWND, HGTwainDSMImpl*> HGTwainDSMImpl::m_mapWnd;
@ -964,8 +965,30 @@ HGResult HGTwainDSImpl::ImageNativeXfer(HGUInt type, HGUInt origin, HGImage* ima
return HGTWAIN_ERR_FAIL;
}
HGResult ret = HGBase_CreateImageFromDIB(hMem, NULL, type, origin, image);
#ifdef _WIN64
HGStream stream = NULL;
HGResult ret = HGBase_CreateDIBStream(hMem, &stream);
GlobalFree(hMem);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
ret = HGBase_CreateImageFromStream(stream, NULL, type, origin, image);
HGBase_DestroyStream(stream);
#else
HGChar tmpFile[260];
HGBase_GetTmpFileName("bmp", tmpFile, 260);
HGResult ret = HGBase_CreateDIBFile(hMem, tmpFile);
GlobalFree(hMem);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
ret = HGBase_CreateImageFromFile(tmpFile, NULL, type, origin, image);
HGBase_DeleteFile(tmpFile);
#endif
return ret;
}