windows小程式-用文字堆壘單色BMP位元影像

來源:互聯網
上載者:User
好久沒更新了……貼一個最近做的圖片轉文字的大小東西吧=w=
#ifndef UNICODE#define UNICODE#endif#ifndef _UNICODE//#define _UNICODE#endif//#include <stdio.h>#include <windows.h>#include <assert.h>#include <malloc.h>LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){static HWND hwndText = NULL;static HWND hwndButton = NULL;static WCHAR *pcnChar = NULL;switch(msg){case WM_CREATE:pcnChar = (WCHAR*)((LPCREATESTRUCT)lParam)->lpCreateParams;hwndText = CreateWindow(L"EDIT", L"",            WS_CHILD | WS_VISIBLE | WS_BORDER,            1, 1, 60, 60,            hwnd, (HMENU)0, ((LPCREATESTRUCT)(lParam))->hInstance, NULL);hwndButton = CreateWindow(L"BUTTON", L"OK",            WS_CHILD | WS_VISIBLE | WS_BORDER,            65, 1, 60, 60,            hwnd, (HMENU)1, ((LPCREATESTRUCT)(lParam))->hInstance, NULL);break;case WM_COMMAND:if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == 1){if(!GetWindowText(hwndText, pcnChar, 2) || *pcnChar < 0xFF){MessageBox(0,L"請輸入一個漢字!",0,0);break;}DestroyWindow(hwnd);}break;case WM_DESTROY:if(!*pcnChar && *pcnChar < 0xFF){MessageBox(0,L"擷取漢字失敗,現在退出",0,0);exit(0);}PostQuitMessage(0);//GetWindowText(hwndText, pcnChar, 1);break;}return DefWindowProc(hwnd,msg,wParam,lParam);}typedef struct{BYTE *byte_ptr;int bit_pointer;}BitPointer;void BitPointerInc(BitPointer *o){assert(0 <= o->bit_pointer && o->bit_pointer < 8);if(o->bit_pointer == 7){o->bit_pointer = 0;o->byte_ptr += 1;}else{o->bit_pointer += 1;}}void SetBit(BitPointer *o){assert(0 <= o->bit_pointer && o->bit_pointer < 8);*(o->byte_ptr) |= (1 << (7 - (o->bit_pointer))); //這裡要注意位元的順序……}int GetBit(BitPointer *o){assert(0 <= o->bit_pointer && o->bit_pointer < 8);return (*(o->byte_ptr)) & (1 << (7 - (o->bit_pointer))); //這裡要注意位元的順序……}void JmpByte(BitPointer *o){o->byte_ptr += 1;o->bit_pointer = 0;}int CountBits(BitPointer *o,BYTE *start){return ((o->byte_ptr) - start) * 8 + (o->bit_pointer);}static WCHAR g_szClassName[] = L"MyWindowClass";static HINSTANCE g_hInstance;int ReadBitmapData(BYTE *buffer,DWORD size,int nWidth,int nHeight,WCHAR **rslt){DWORD bitLineLength = (nWidth % 32 == 0)? nWidth: 32 - nWidth % 32 + nWidth;WCHAR **bitLine = NULL;int i,j;bitLine = (WCHAR**)malloc(nHeight * sizeof(WCHAR*));BitPointer ptr = { buffer, 0 };  for(i = nHeight - 1; i >= 0; --i){bitLine[i] = (WCHAR*)malloc(nWidth * sizeof(WCHAR));ZeroMemory(bitLine[i],nWidth * sizeof(WCHAR));for(j = 0; j < nWidth; ++j,BitPointerInc(&ptr)){bitLine[i][j] = !GetBit(&ptr);}while(CountBits(&ptr, buffer) % bitLineLength != 0){JmpByte(&ptr);}}static WCHAR cnChar[2] = L"\0";HWND hwnd = CreateWindow(g_szClassName,L"輸入一個漢字",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 240, 100,NULL, NULL, g_hInstance, cnChar);ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}if(*cnChar == L'\0'){MessageBox(0,L"程式出錯,請向程式作者報告這個錯誤",0,0);}for(i = 0; i < nHeight; ++i){bitLine[i] = (WCHAR*)realloc(bitLine[i],(nWidth+2)*sizeof(WCHAR));bitLine[i][nWidth] = L'\r';bitLine[i][nWidth+1] = L'\n';for(j = 0; j < nWidth; ++j){if(bitLine[i][j])bitLine[i][j] = *cnChar;else bitLine[i][j] = L' ';}if(i > 0){bitLine[0] = (WCHAR*)realloc(bitLine[0],(i + 1)*(2 + nWidth) * sizeof(WCHAR));memcpy(bitLine[0] + ((i) * (2 + nWidth)),bitLine[i],(2 + nWidth) * sizeof(WCHAR));free(bitLine[i]);}}int nRslt = 1 + (i)*(2 + nWidth);bitLine[0] = (WCHAR*)realloc(bitLine[0],nRslt * sizeof(WCHAR));*(bitLine[0] + (i)*(2 + nWidth)) = 0;//terminate the unicode string#ifdef _DEBUGMessageBox(0,bitLine[0],0,0);#endif*rslt = bitLine[0];free(bitLine);return nRslt;}void Process(PWSTR filename){//MessageBox(0,filename,0,0);HANDLE hFile = CreateFile(filename, GENERIC_READ,FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);assert(hFile != INVALID_HANDLE_VALUE);static BYTE buffer[8192];ZeroMemory(buffer,sizeof buffer);DWORD dwRead;assert(ReadFile(hFile, buffer, 2, &dwRead, NULL));assert(2 == dwRead);if(!!strcmp("BM",(const char*)buffer)){MessageBox(0,L"不是有效BMP檔案",0,0);exit(0);}assert(SetFilePointer(hFile,0x0E,0,FILE_BEGIN)); //跳過影像檔頭//讀映像資訊頭的第一個項,Bitmap Header Size,佔2個雙字assert(ReadFile(hFile, buffer, 4, &dwRead, NULL)); assert(4 == dwRead && 4 == sizeof(DWORD));//*************************************************//測試電腦的位元組序,暫時只支援小端對齊{BYTE edian_test[4] = { 0xAa, 0xBb, 0xCc, 0xDd };if((DWORD)0xDdCcBbAa != *(DWORD*)edian_test){MessageBox(0,L"程式暫不支援大端的處理器\n"L"您可能在某些處理器上運行WinCE\n"L"或在ARM處理器上運行案頭版的Windows 8\n"L"本程式暫不處理這些情況,程式現在退出",L"程式的版本需要為此電腦更新",0);exit(0);}}//**************************************************/////if(*(DWORD*)buffer != 0x28) //映像資訊頭的大小應為0x28{MessageBox(0,L"不認識這個類型的BMP檔案,"L"如無特別原因請用Windows內建畫圖程式產生單色BMP檔案",0,0);exit(0);}assert(SetFilePointer(hFile,0x02,0,FILE_BEGIN));assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);if(GetFileSize(hFile,NULL) != *(DWORD*)buffer){wsprintf((PWSTR)buffer,L"BMP檔案具有錯誤的檔案大小,應為%d位元組,實際為%d位元組",*(DWORD*)buffer,GetFileSize(hFile,NULL));MessageBox(0,(PWSTR)buffer,L"影像檔破損",0);exit(0);}DWORD dwFileSize = *(DWORD*)buffer;assert(SetFilePointer(hFile,0x1C,0,FILE_BEGIN));assert(ReadFile(hFile, buffer, 2, &dwRead, NULL));assert(2 == dwRead);if(*(WORD*)buffer != 0x01) //mono BMP{MessageBox(0,L"這是一個正確的BMP檔案,但本程式用於將單色BMP轉為文字"L"如無特別原因請用Windows內建畫圖程式產生單色BMP檔案\n"L"或使用Windows內建畫圖程式開啟此圖片後重新另存新檔單色BMP",0,0);exit(0);}assert(ReadFile(hFile, buffer, 2, &dwRead, NULL));assert(2 == dwRead);if(*(WORD*)buffer != 0){MessageBox(0,L"這是一個正確的單色BMP檔案\n"L"但本程式暫時不處理此圖片使用的RLE壓縮方式\n"L"如無特別原因請用Windows內建畫圖程式產生單色BMP檔案\n"L"或使用Windows內建畫圖程式開啟此圖片後重新另存新檔單色BMP",L"需要更新程式版本來支援此圖片",0);exit(0);}assert(SetFilePointer(hFile,0x12,0,FILE_BEGIN));DWORD nWidth,nHeight;assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);nWidth = *(DWORD*)buffer;assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);nHeight = *(DWORD*)buffer;assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);if(0x00010001 != *(DWORD*)buffer) //小端位元組序{MessageBox(0,L"位面數和像素佔用位元應為1",L"破損的單色BMP圖片",0);exit(0);}DWORD dwStartOffset = 0;assert(SetFilePointer(hFile,0x0A,0,FILE_BEGIN));assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);dwStartOffset = *(DWORD*)buffer;assert(SetFilePointer(hFile,0x22,0,FILE_BEGIN));assert(ReadFile(hFile, buffer, 4, &dwRead, NULL));assert(4 == dwRead);DWORD dwBitmapDataSize = *(DWORD*)buffer;if(dwBitmapDataSize != dwFileSize - dwStartOffset){MessageBox(0,L"BMP檔案破損,資料不一致",0,0);exit(0);}assert(SetFilePointer(hFile,dwStartOffset,0,FILE_BEGIN));BYTE *dataSpace = (BYTE*)malloc(dwBitmapDataSize);assert(dataSpace);assert(ReadFile(hFile, dataSpace, dwBitmapDataSize, &dwRead, NULL));assert(dwBitmapDataSize == dwRead);WCHAR *rslt = NULL;int nRslt = ReadBitmapData(dataSpace,dwBitmapDataSize,nWidth,nHeight,&rslt);free(dataSpace);dataSpace = NULL;HGLOBAL gData = GlobalAlloc(GMEM_MOVEABLE,nRslt * sizeof(WCHAR));void *p = GlobalLock(gData);assert(p);memcpy(p,rslt,nRslt * sizeof(WCHAR));OpenClipboard(NULL);EmptyClipboard();SetClipboardData(CF_UNICODETEXT,gData);CloseClipboard();GlobalUnlock(gData);GlobalFree(gData);MessageBox(0,L"結果已儲存到剪下板,現在可以把結果黏貼到任意位置了",L"",0);}int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hpreInst,PSTR lpCmdLine,int nShow){g_hInstance = hinst;OPENFILENAME ofn;WCHAR szFileName[MAX_PATH] = L"";ZeroMemory(&ofn, sizeof(ofn));ofn.lStructSize = sizeof(ofn);ofn.lpstrFilter = L"Text Files (*.bmp)\0*.bmp\0All Files (*.*)\0*.*\0\0";ofn.lpstrFile = szFileName;ofn.nMaxFile = MAX_PATH;ofn.lpstrDefExt = L"bmp";ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;if(!GetOpenFileName(&ofn)){MessageBox(0,L"尋找檔案失敗",0,0);return 0;}WNDCLASS WndClass = {0};WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);WndClass.lpfnWndProc   = WndProc;WndClass.lpszClassName = g_szClassName;if(!RegisterClass(&WndClass)){MessageBox(0, L"Window Registration Failed!", L"Error!",MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);return 0;}Process(szFileName);return 0;}

我把它叫做bmp-to-text.c程式呵呵~

gcc -o b2t bmp-to-text.c -finput-charset=gbk -mwindows

把BMP單色位元影像轉換成文字。。。

例如做一個位元影像,在位元影像上畫一個雲字,可以產生下面的效果:

     云云云云云云云云云云云云云云云云云云云云云云雲            
     云云云云云云云云云云云云云云云云云云云云云云雲            
                                        
                                        
                                        
                                        
                                        
                                        
                                        
                                        
  云云云云云云云云云云云云云云云云云云云云云云云云云云云云雲         
  云云云云云云云云云云云云云云云云云云云云云云云云云云云云雲         
             云云雲                        
            云云雲                         
            云云雲                         
           云云雲                          
           云云雲       雲                  
          云云雲       云云雲                 
          云云雲        云云雲                
         云云雲         云云雲                
        云云雲           云云雲               
        云云雲            云云雲              
       云云雲             云云云云             
      云云雲               云云雲             
     云云云云                云云雲            
    云云云云云云云云云云云云云云云云云云云云云云云云雲           
     云云云云云云云云云云云云         云云雲           
     雲                     云云雲          
                            雲           

也就是沒事隨便玩玩~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.