PDA

View Full Version : حرفه ای: عکس گرفتن از صفحه نمایش



mvb_mehran
پنج شنبه 26 تیر 1393, 02:06 صبح
سلام
چطور میشه از صفحه نمایش عکس گرفت و اونو ذخیره کرد؟
ممنون

Coder#
پنج شنبه 26 تیر 1393, 12:13 عصر
سلام
چطور میشه از صفحه نمایش عکس گرفت و اونو ذخیره کرد؟
ممنون

سلام.
مطمئن نیستم که این یک سوال برنامه نویسیه یا مرتبط با عکس گیری از یک محیط.
- اگر قصد عکس گرفتن از محیطی در سیستم عامل ویندوز رو داری، نرم افزار Snipping Tool کارآمده.
- اگر قصد عکس گرفتن از محیطی در سیستم عامل لینوکس رو داری، به این لینک (http://ostatic.com/blog/six-top-screen-capture-tools-for-linux) مراجعه کن.
اما به نظرم سوالات این چنینی رو باید در این بخش (http://barnamenevis.org/forumdisplay.php?171-%DA%AF%D9%81%D8%AA%DA%AF%D9%88%DB%8C-%D8%B9%D9%85%D9%88%D9%85%DB%8C-%DA%A9%D8%A7%D9%85%D9%BE%DB%8C%D9%88%D8%AA%D8%B1-%D9%88-%D9%81%D9%86%D8%A7%D9%88%D8%B1%DB%8C-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA) پرسید.:لبخندساده:

کامبیز اسدزاده
پنج شنبه 26 تیر 1393, 12:24 عصر
سلام
چطور میشه از صفحه نمایش عکس گرفت و اونو ذخیره کرد؟
ممنون

سلام

این یک نمونه هستش توسط هیدر Windows.h


#include<Windows.h>


void ScreenShot(char*BmpName)
{
HWND DesktopHwnd = GetDesktopWindow();
RECT DesktopParams;
HDC DevC = GetDC(DesktopHwnd);
GetWindowRect(DesktopHwnd,&DesktopParams);
DWORD Width = DesktopParams.right - DesktopParams.left;
DWORD Height = DesktopParams.bottom - DesktopParams.top;


DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ (sizeof(RGBTRIPLE)+1*(Width*Height*4));
char *BmpFileData = (char*)GlobalAlloc(0x0040,FileSize);


PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];


BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);


BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;


RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;

HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC,Width,Height);
SelectObject(CaptureDC,CaptureBitmap);
BitBlt(CaptureDC,0,0,Width,Height,DevC,0,0,SRCCOPY |CAPTUREBLT);
GetDIBits(CaptureDC,CaptureBitmap,0,Height,Image,( LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);


DWORD Junk;
HANDLE FH = CreateFileA(BmpName,GENERIC_WRITE,FILE_SHARE_WRITE ,0,CREATE_ALWAYS,0,0);
WriteFile(FH,BmpFileData,FileSize,&Junk,0);
CloseHandle(FH);
GlobalFree(BmpFileData);
}


int main()
{
ScreenShot("Hello.bmp");
}


به این مثال هم توجه کنید : http://stackoverflow.com/questions/7292757/how-to-get-screenshot-of-a-window-as-bitmap-object-in-c

mvb_mehran
پنج شنبه 26 تیر 1393, 14:15 عصر
سلام.
قصدم عکس گرفتن از صفحه نمایش توسط کدنویسیه.

mvb_mehran
پنج شنبه 26 تیر 1393, 14:27 عصر
سلام

این یک نمونه هستش توسط هیدر Windows.h


#include<Windows.h>


void ScreenShot(char*BmpName)
{
HWND DesktopHwnd = GetDesktopWindow();
RECT DesktopParams;
HDC DevC = GetDC(DesktopHwnd);
GetWindowRect(DesktopHwnd,&DesktopParams);
DWORD Width = DesktopParams.right - DesktopParams.left;
DWORD Height = DesktopParams.bottom - DesktopParams.top;


DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ (sizeof(RGBTRIPLE)+1*(Width*Height*4));
char *BmpFileData = (char*)GlobalAlloc(0x0040,FileSize);


PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];


BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);


BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;


RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;

HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC,Width,Height);
SelectObject(CaptureDC,CaptureBitmap);
BitBlt(CaptureDC,0,0,Width,Height,DevC,0,0,SRCCOPY |CAPTUREBLT);
GetDIBits(CaptureDC,CaptureBitmap,0,Height,Image,( LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);


DWORD Junk;
HANDLE FH = CreateFileA(BmpName,GENERIC_WRITE,FILE_SHARE_WRITE ,0,CREATE_ALWAYS,0,0);
WriteFile(FH,BmpFileData,FileSize,&Junk,0);
CloseHandle(FH);
GlobalFree(BmpFileData);
}


int main()
{
ScreenShot("Hello.bmp");
}


به این مثال هم توجه کنید : http://stackoverflow.com/questions/7292757/how-to-get-screenshot-of-a-window-as-bitmap-object-in-c
ممنون کاملا درست کار می کنه.اما فرمت تصویر bmp هست و خیلی حجم سنگینی ذخیره میشه.نمیشه کاری کرد فرمت به jpg تبدیل بشه؟

کامبیز اسدزاده
پنج شنبه 26 تیر 1393, 15:09 عصر
ممنون کاملا درست کار می کنه.اما فرمت تصویر bmp هست و خیلی حجم سنگینی ذخیره میشه.نمیشه کاری کرد فرمت به jpg تبدیل بشه؟


این رو امتحان کنید ... یکمی حجم کاهش پیدا کرد.


#include<Windows.h>


void ScreenShot(char*BmpName)
{
HWND DesktopHwnd = GetDesktopWindow();
RECT DesktopParams;
HDC DevC = GetDC(DesktopHwnd);
GetWindowRect(DesktopHwnd,&DesktopParams);
DWORD Width = DesktopParams.right - DesktopParams.left;
DWORD Height = DesktopParams.bottom - DesktopParams.top;


DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ (sizeof(RGBTRIPLE)+1*(Width*Height*4));
char *BmpFileData = (char*)GlobalAlloc(0x0040,FileSize);



PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];


BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);


BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;


RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;

HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC,Width,Height);
SelectObject(CaptureDC,CaptureBitmap);
BitBlt(CaptureDC,0,0,Width,Height,DevC,0,0,SRCCOPY |CAPTUREBLT);
GetDIBits(CaptureDC,CaptureBitmap,0,Height,Image,( LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);


DWORD Junk;
HANDLE FH = CreateFileA(BmpName,GENERIC_WRITE,FILE_SHARE_WRITE ,0,CREATE_ALWAYS,0,0);
WriteFile(FH,BmpFileData,FileSize - 1000000,&Junk,0);
CloseHandle(FH);
GlobalFree(BmpFileData);
}


int main()
{
ScreenShot("Hello.bmp");
}

#target
جمعه 27 تیر 1393, 01:22 صبح
با GDI+هم میشه عکسو تبدیل به JPEG کرد
مثلا همون تبدیل.. تابع زیر رو اول تعریف کن
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}


سپس بعد از فراخوانی تابع ذخیره اینطور بنویس
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Image image(L"Hello.bmp");
CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg", &jpgClsid);
image.Save(L"Hello.jpg", &jpgClsid, NULL);
اینام نیازه اضافه شه
#include <GDIPlus.h>
using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")

mvb_mehran
جمعه 27 تیر 1393, 02:47 صبح
از دوستان واقعا ممنونم.کارم درست شد.

sa1378
جمعه 27 تیر 1393, 16:43 عصر
چرا کد برای من کار نمیکنه؟
این ارور رو میده:
121264

#target
شنبه 28 تیر 1393, 00:16 صبح
بعیده ولی اینو اضافه کن اول برنامت ببین چی میشه ؟
#define CAPTUREBLT 0x40000000

a.r.khoshghalb
شنبه 28 تیر 1393, 04:37 صبح
سلام.
مطمئن نیستم که این یک سوال برنامه نویسیه یا مرتبط با عکس گیری از یک محیط.
- اگر قصد عکس گرفتن از محیطی در سیستم عامل ویندوز رو داری، نرم افزار Snipping Tool کارآمده.
- اگر قصد عکس گرفتن از محیطی در سیستم عامل لینوکس رو داری، به این لینک (http://ostatic.com/blog/six-top-screen-capture-tools-for-linux) مراجعه کن.
اما به نظرم سوالات این چنینی رو باید در این بخش (http://barnamenevis.org/forumdisplay.php?171-%DA%AF%D9%81%D8%AA%DA%AF%D9%88%DB%8C-%D8%B9%D9%85%D9%88%D9%85%DB%8C-%DA%A9%D8%A7%D9%85%D9%BE%DB%8C%D9%88%D8%AA%D8%B1-%D9%88-%D9%81%D9%86%D8%A7%D9%88%D8%B1%DB%8C-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA) پرسید.:لبخندساده:

واقعا چرا فکر کردی منظورش عکس گرفتن با کمک نرم افزار های آماده سیستم عامل بوده؟ :متفکر: