在发表这篇文章之前,我搜索并尝试了4天所有的事情,比如https://www.codeproject.com/kb/gdi-plus/memimage.aspx,但我是编程新手。
这段代码(不是我的),制作了一个打印屏幕,保存到文件然后发送到ftp服务器。我想这样做而不将文件保存到HDD,从内存到FTP。
// The print-screen and save to file (jpg) code:
wstring wtmp;
tmp = sDate + pictureName + ".jpeg";
wtmp = ToStringW(tmp);
screenName = wtmp.c_str();
ftpScreenName = wtmp.c_str();
fileToRemove = tmp.c_str();
using namespace Gdiplus;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
{
HDC scrdc, memdc;
HBITMAP membit;
scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, membit);
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
Gdiplus::Bitmap bitmap(membit, NULL);
EncoderParameters encoderParameters;
ULONG quality;
CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
// Save the image as a JPEG with quality level 80.
quality = 80;
encoderParameters.Parameter[0].Value = &quality;
int result;
result = bitmap.Save(screenName, &clsid); //saving the file to HDD
//send to ftp with given info
saveFTP(server, user, password, ftpScreenName, screenName);
}
GdiplusShutdown(gdiplusToken);
//这里是FTP客户端部分:
bool saveFTP(LPCWSTR l_server, LPCWSTR l_user, LPCWSTR l_pass, LPCWSTR l_ftpfile, LPCWSTR l_screen)
{
HINTERNET internet = InternetOpen(L"tester", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
HINTERNET inter = InternetConnect(internet, l_server, INTERNET_DEFAULT_FTP_PORT, l_user, l_pass, INTERNET_SERVICE_FTP, 0, 0);
bool result;
result = FtpPutFile(inter, l_screen, l_ftpfile, FTP_TRANSFER_TYPE_BINARY, 0);
InternetCloseHandle(inter);
InternetCloseHandle(internet);
return result;
}
答案 0 :(得分:1)
使用FtpOpenFile()
和InternetWriteFile()
代替FtpPutFile()
。这在FtpPutFile()
文档中明确说明:
FtpPutFile
是一个高级例程,它处理与在本地读取文件并将其存储在FTP服务器上相关的所有簿记和开销。 只需要发送文件数据或需要严格控制文件传输的应用程序应使用FtpOpenFile
和InternetWriteFile
函数。
以及WinInet的FTP Sessions文档
要在FTP服务器上传或放置文件,应用程序可以使用
FtpPutFile
或FtpOpenFile
(以及InternetWriteFile
)。如果文件已在本地存在,则可以使用FtpPutFile
;如果需要将数据写入FTP服务器上的文件,则可以使用FtpOpenFile
和InternetWriteFile
。
Gdiplus::Bitmap
可以保存为HDD文件或IStream
。您可以使用
CreateStreamOnHGlobal()
或SHCreateMemStream()
创建内存流,然后将Bitmap
保存到流中,最后使用FtpOpenFile()
和InternetWriteFile()
上传流的内容
例如(为简洁省略了错误处理,请不要在实际代码中省略它!):
tmp = sDate + pictureName + ".jpeg";
wstring wtmp = ToStringW(tmp);
IStream *strm = SHCreateMemStream(NULL, 0);
using namespace Gdiplus;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
// Save the image as a JPEG with quality level 80.
ULONG quality = 80;
encoderParameters.Parameter[0].Value = &quality;
HDC scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
HDC memdc = CreateCompatibleDC(scrdc);
HBITMAP membit = CreateCompatibleBitmap(scrdc, Width, Height);
HBITMAP hOldBitmap = (HBITMAP) SelectObject(memdc, membit);
BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
{
Gdiplus::Bitmap bitmap(membit, NULL);
bitmap.Save(strm, &clsid); //saving the file to HDD
}
SelectObject(memdc, hOldBitmap);
DeleteObject(membit);
DeleteDC(memdc);
::ReleaseDC(0, scrdc);
GdiplusShutdown(gdiplusToken);
LARGE_INTEGER li;
li.QuadPart = 0;
strm->Seek(li, STREAM_SEEK_SET, NULL);
//send to ftp with given info
saveFTP(server, user, password, wtmp.c_str(), strm);
strm->Release();
bool saveFTP(LPCWSTR l_server, LPCWSTR l_user, LPCWSTR l_pass, LPCWSTR l_ftpfile, IStream *l_screen)
{
HINTERNET internet = InternetOpen(L"tester", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
HINTERNET conn = InternetConnect(internet, l_server, INTERNET_DEFAULT_FTP_PORT, l_user, l_pass, INTERNET_SERVICE_FTP, 0, 0);
HINTERNET file = FtpOpenFile(conn, l_ftpfile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0);
BYTE buffer[1024], *pbuf;
ULONG ulRead;
DWORD dwWritten;
HRESULT hr;
bool success = true;
do
{
hr = l_screen->Read(buffer, sizeof(buffer), &ulRead);
if (FAILED(hr))
{
success = false;
break;
}
pbuf = buffer;
while (ulRead != 0)
{
if (!InternetWriteFile(file, pbuf, ulRead, &dwWritten))
{
success = false;
break;
}
pbuf += dwWritten;
ulRead -= dwWritten;
}
}
while (hr == S_OK);
InternetCloseHandle(file);
InternetCloseHandle(conn);
InternetCloseHandle(internet);
return success;
}