图片取模软件工具推荐:Img2Lcd.exe 【支持JPG、BMP、EMF、WBMP、GIF、ICO】
//imgData:RGB888格式数据
//width:图片宽度px
//height:图片高度px
//CMFCApplication1Dlg:自定义的项目MFC对话框类
void Cxxxx::DrawPic(char *imgData,int width,int height)
{
if (imgData == NULL) {
return;
}
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);
//建立一个与屏幕显示兼容的位图,位图的大小可以用窗口的大小
CRect rcClient;
GetClientRect(&rcClient);
static CDC* pDC = GetDC();
MemBitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap* pOldBit = MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净.
MemDC.FillSolidRect(0, 0, rcClient.Width(), rcClient.Height(),
RGB(31, 204, 160));//绘图
//start draw data==================
CPoint pt;
COLORREF color = RGB(0, 0, 0);
long index = 0;
for (size_t i = 0; i < height; i++)
{
for (size_t j = 0; j < width; j++)
{
pt.x = j;
pt.y = i;
color = RGB(imgData[index], imgData[index + 1], imgData[index + 2]);
index += 4;//R_G_B_Alpha
MemDC.SetPixel(pt, color);//大图片比较耗时
}
}
//end draw data=================
//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(),
&MemDC, 0, 0, SRCCOPY);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
}
//------------------------------------------
//截取整屏幕保存到g_ScreenData数组
/* Globals */
int g_ScreenX = 0;
int g_ScreenY = 0;
BYTE* g_ScreenData = 0;
void ScreenCap()
{
HDC hScreen = GetDC(NULL);
g_ScreenX = GetDeviceCaps(hScreen, HORZRES);
g_ScreenY = GetDeviceCaps(hScreen, VERTRES);
HDC hdcMem = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, g_ScreenX, g_ScreenY);
HGDIOBJ hOld = SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, g_ScreenX, g_ScreenY, hScreen, 0, 0, SRCCOPY);
SelectObject(hdcMem, hOld);
BITMAPINFOHEADER bmi = { 0 };
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biWidth = g_ScreenX;
bmi.biHeight = -g_ScreenY;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0;// 3 * ScreenX * ScreenY;
if (g_ScreenData)
free(g_ScreenData);
g_ScreenData = (BYTE*)malloc(4 * g_ScreenX * g_ScreenY);
GetDIBits(hdcMem, hBitmap, 0, g_ScreenY, g_ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
ReleaseDC(GetDesktopWindow(), hScreen);
DeleteDC(hdcMem);
DeleteObject(hBitmap);
}
inline int GetScreenPixelB(int x, int y)
{
return g_ScreenData[4 * ((y * g_ScreenX) + x)];
}
inline int GetScreenPixelG(int x, int y)
{
return g_ScreenData[4 * ((y * g_ScreenX) + x) + 1];
}
inline int GetScreenPixelR(int x, int y)
{
return g_ScreenData[4 * ((y * g_ScreenX) + x) + 2];
}
//------------------------------------
void Cxxxx::DrawBitmap(uint8_t* imgData, int bitCount, int width, int height)
{
#define PC_BITCOUNT 32 //电脑固定32bit图像位数
#define RGB565_RED 0xf800
#define RGB565_GREEN 0x07e0
#define RGB565_BLUE 0x001f
//uint8_t* imgDataOut = (uint8_t*)malloc(width * height * (LV_COLOR_DEPTH / 8));
long pixelCount = width * height;
uint8_t* imgDataOut = (uint8_t*)malloc(pixelCount * 4);//32 BIT 图像
if (bitCount == 16)
{
long i = 0;
long j = 0;
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
uint16_t n565Color = 0;
do
{
n565Color = (imgData[j] << 8) | imgData[j + 1];
b = (n565Color & RGB565_RED) >> 8;
g = (n565Color & RGB565_GREEN) >> 3;
r = (n565Color & RGB565_BLUE) << 3;
j += 2;
imgDataOut[i + 0] = r;
imgDataOut[i + 1] = g;
imgDataOut[i + 2] = b;
imgDataOut[i + 3] = 0x00;
i += 4;
} while (j < pixelCount * bitCount / 8);
}
else if (bitCount == 24)
{
long i = 0;
long j = 0;
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
do
{
b = imgData[j + 0];
g = imgData[j + 1];
r = imgData[j + 2];
j += 3;
imgDataOut[i + 0] = r;
imgDataOut[i + 1] = g;
imgDataOut[i + 2] = b;
imgDataOut[i + 3] = 0x00;
i += 4;
} while (j < pixelCount * bitCount / 8);
}
else if (bitCount == 32)
{
memcpy(imgDataOut, imgData, pixelCount * 4);
}
static CDC* pDC = GetDC();
HBITMAP hBitMap = CreateBitmap(width, height, 1, PC_BITCOUNT, imgDataOut);
CBitmap cbmp;
CDC dcMemory;
cbmp.Attach(hBitMap);
dcMemory.CreateCompatibleDC(pDC);
CBitmap* hOldBitmap = dcMemory.SelectObject(&cbmp);
pDC->BitBlt(0, 0, width, height,
&dcMemory,
0, 0,
SRCCOPY);
cbmp.DeleteObject();
dcMemory.SelectObject(hOldBitmap);
dcMemory.DeleteDC();
#if 0
CString str;
str.Format("DrawData_%dBit",bitCount);
DumpHex("DrawData", imgDataOut, pixelCount * 4);
#endif
free(imgDataOut);
}
void BlockTransfer(int x0,int y0,int imgW,int imgH,uint8_t * imageData)
{
//g_screenBuffer为整个屏幕的buffer,宽度:SCREEN_WIDTH,高度:SCREEN_HEIGH
//源图长宽为sW,sH;在(x0,y0)位置覆盖 imageData 图形数据 长宽 imgW,imgH;
int x = 0;
int y = 0;
int posDest = 0;
int posSrc = 0;
for (int j = 0;j < imgH;j++)
{
y = y0 + j;
if (y > SCREEN_HEIGH)
break;
for (int i = 0; i < imgW; i++)
{
x = x0 + i;
if (x > SCREEN_WIDTH)
break;
posDest = x + SCREEN_WIDTH * y;
posSrc = i + imgH * j;
//请判断坐标是否越界if
//32BIT(4Byte)图处理方式:
g_screenBuffer[4 * posDest + 0] = imageData[4 * posSrc + 0];
g_screenBuffer[4 * posDest + 1] = imageData[4 * posSrc + 1];
g_screenBuffer[4 * posDest + 2] = imageData[4 * posSrc + 2];
g_screenBuffer[4 * posDest + 3] = imageData[4 * posSrc + 3];
}
}
}
void BlockTransfer(int x0,int y0,int imgW,int imgH,uint8_t * imageData,bool bEnableFilter=false, uint32_t filterColor=0)
{
//g_screenBuffer为整个屏幕的buffer,宽度:SCREEN_WIDTH,高度:SCREEN_HEIGH
//源图长宽为sW,sH;在(x0,y0)位置覆盖 imageData 图形数据 长宽 imgW,imgH;
//bEnableFilter 允许过滤色, filterColor 过滤像素的RGB值
int x = 0;
int y = 0;
int posDest = 0;
int posSrc = 0;
uint8_t r, g, b;
uint32_t nColorCmp;
for (int j = 0;j < imgH;j++)
{
y = y0 + j;
if (y > SCREEN_HEIGH)
break;
for (int i = 0; i < imgW; i++)
{
x = x0 + i;
if (x > SCREEN_WIDTH)
break;
posDest = x + SCREEN_WIDTH * y;
posSrc = i + imgH * j;
//请注意判断坐标是否越界
//32BIT(4Byte)图处理方式:
r = imageData[4 * posSrc + 0];
g = imageData[4 * posSrc + 1];
b = imageData[4 * posSrc + 2];
if (bEnableFilter) {
nColorCmp = (r << 16) | (g << 8) | (b);
if (nColorCmp == filterColor) {
continue;
}
}
g_screenBuffer[4 * posDest + 0] = imageData[4 * posSrc + 0];
g_screenBuffer[4 * posDest + 1] = imageData[4 * posSrc + 1];
g_screenBuffer[4 * posDest + 2] = imageData[4 * posSrc + 2];
g_screenBuffer[4 * posDest + 3] = imageData[4 * posSrc + 3];
}
}
}
void qt_draw_bitmap(uint8_t* imgData, int bitCount, uint16_t width, uint16_t height, QPainter* paint)
{
//#include <QPainter>
#define RGB565_RED 0xf800
#define RGB565_GREEN 0x07e0
#define RGB565_BLUE 0x001f
long pixelCount = width * height;
uint8_t* imgDataOut = (uint8_t*)malloc(pixelCount * 4);//32 BIT 图像
if (bitCount == 16)
{
long i = 0;
long j = 0;
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
uint16_t n565Color = 0;
do
{
n565Color = (imgData[j] << 8) | imgData[j + 1];
b = (n565Color & RGB565_RED) >> 8;
g = (n565Color & RGB565_GREEN) >> 3;
r = (n565Color & RGB565_BLUE) << 3;
j += 2;
imgDataOut[i + 0] = r;
imgDataOut[i + 1] = g;
imgDataOut[i + 2] = b;
imgDataOut[i + 3] = 0x00;
i += 4;
} while (j < pixelCount * bitCount / 8);
}
else if (bitCount == 24)
{
long i = 0;
long j = 0;
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
do
{
b = imgData[j + 0];
g = imgData[j + 1];
r = imgData[j + 2];
j += 3;
imgDataOut[i + 0] = r;
imgDataOut[i + 1] = g;
imgDataOut[i + 2] = b;
imgDataOut[i + 3] = 0x00;
i += 4;
} while (j < pixelCount * bitCount / 8);
}
else if (bitCount == 32)
{
memcpy(imgDataOut, imgData, pixelCount * 4);
}
QByteArray imageByteArray = QByteArray((const char*)imgDataOut, pixelCount * 4);
uchar* transData = (unsigned char*)imageByteArray.data();
QImage image = QImage(transData, width, height, QImage::Format_RGB32);
free(imgDataOut);
paint->drawImage(QPoint(0, 0), image);//start point=[0,0]
paint->end();
}
void qt_draw_bitmap(uint8_t *imgData16Bit, uint16_t width, uint16_t height, QLabel *label)
{
long pixelCount = width * height;
QByteArray imageByteArray = QByteArray((const char *) imgData16Bit, pixelCount * 2);
uchar *transData = (unsigned char *) imageByteArray.data();
QImage image = QImage(transData, width, height, QImage::Format_RGB16);//RGB565_16bit
QPixmap tmpPixmap = QPixmap::fromImage(image);
label->setPixmap(tmpPixmap);
}
#include <stdio.h>
#include <SDL2/SDL.h>
#define SDL_HOR_RES (800)
#define SDL_VER_RES (600)
typedef struct TagMonitor
{
int screen_w;
int screen_h;
SDL_Renderer *render;
SDL_Texture *texture;
} tagMonitor;
// 将屏幕设置成指定argb颜色
int update_win(tagMonitor *mt, uint32_t argb)
{
uint32_t fb_data[SDL_HOR_RES * SDL_VER_RES]; // frame buffer data[w*h]
for (size_t i = 0; i < SDL_HOR_RES * SDL_VER_RES; i++)
{
fb_data[i] = argb;
}
SDL_UpdateTexture(mt->texture, NULL, fb_data, mt->screen_w * 4);
SDL_RenderClear(mt->render);
// 设定渲染的目标区域
SDL_Rect destRect;
destRect.x = 0;
destRect.y = 0;
destRect.w = mt->screen_w;
destRect.h = mt->screen_h;
// 复制材质到渲染器对象
if (SDL_RenderCopy(mt->render, mt->texture, NULL, &destRect))
{
printf("Error,%s \n", SDL_GetError());
return -1;
}
// 执行渲染操作
SDL_RenderPresent(mt->render);
return 0;
}
int main(void *arg)
{
// 窗口大小
int screen_w = SDL_HOR_RES;
int screen_h = SDL_VER_RES;
// 初始化SDL
if (SDL_Init(SDL_INIT_EVERYTHING))
{
printf("could not initialize SDL: %s\n", SDL_GetError());
return -1;
}
SDL_Window *screen = SDL_CreateWindow("SimpleSDL2", 0, 0, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!screen)
{
printf("could not create window: %s\n", SDL_GetError());
return -1;
}
SDL_Renderer *render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
if (!render)
{
printf("render create fail! \n");
return -1;
}
SDL_Texture *texture = SDL_CreateTexture(render, // 指定在哪个渲染器当中创建
SDL_PIXELFORMAT_ARGB8888, // 指定当前材质的像素格式
SDL_TEXTUREACCESS_STREAMING, // 设定当前材质可修改
screen_w, screen_h // 指定材质宽高
);
if (!texture)
{
printf("texture create fail! \n");
return -1;
}
tagMonitor mt;
mt.screen_w = screen_w;
mt.screen_h = screen_h;
mt.texture = texture;
mt.render = render;
SDL_Event myEvent; // SDL事件
int quit = 0;
while (!quit) // 建立事件主循环
{
// 注意:事件只针对SDL创建的窗口内有效
while (SDL_PollEvent(&myEvent)) // 从队列里取出事件
{
// printf("event=%d \n", myEvent.type);
switch (myEvent.type) // 根据事件类型分门别类去处理
{
case SDL_QUIT: // 离开事件[点击窗口关闭]
quit = 1; // quit event poll
break;
case SDL_MOUSEMOTION: // 鼠标移动
printf("mouseXY: %d,%d \n", myEvent.motion.x, myEvent.motion.y);
break;
case SDL_MOUSEBUTTONDOWN: // 鼠标点击
printf("ButtonClck:%d\n", myEvent.button.button); // 0:左键,1:中键,2:右键
break;
case SDL_KEYDOWN: // 键盘按下
// 键值表在SDL2/SDL_keycode.h文件中定义
printf("KEY_DOWN:%d\n", myEvent.key.keysym.sym);
break;
case SDL_KEYUP: // 键盘释放
// 键值表在SDL2/SDL_keycode.h文件中定义
printf("KEY_UP:%d\n", myEvent.key.keysym.sym);
break;
}
}
static int cnt = 0;
static int index = 0;
static uint32_t argb = 0xffffffff;
if (cnt++ > 1000)
{
if (index == 0)
argb = 0xFFFF0000; // R
if (index == 1)
argb = 0xFF00FF00; // G
if (index == 2)
argb = 0xFF0000FF; // B
if (index == 3)
argb = 0xFFFFFF00; // Yellow
printf("argb index=%d.\n", index);
cnt = 0;
index = (index + 1) % 4;
}
update_win(&mt, argb);
} //<< while(1)
printf("quit screen_monitor_thread.! \n");
exit(0);
return 0;
}