سؤال

ولدي كاميرا تقوم بإرجاع الصور الخام التي يمكن بسهولة تحويلها إلى صورة نقطية التي يمكن حفظها إلى ملف ما يلي C # طريقة (أي أنا لم أكتب). من مصادر مختلفة، قررت أن هذه الصور لديك 8 بت لكل بكسل، وقد تكون أو لا تكون ذات درجات الرمادي.

private void rawImgToBmp(byte[] imgData, String fname) {
        Bitmap bmp = new Bitmap(getWidth(), getHeight(), 
            System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
        for (int i = 0; i < 256; i++)
            { bmp.Palette.Entries[i] = Color.FromArgb(255, i, i, i); }
        //Copy the data from the byte array into the bitmap
        BitmapData bmpData = 
            bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height),
                          ImageLockMode.WriteOnly, bmp.PixelFormat);
        Marshal.Copy(imgData, 0, bmpData.Scan0, getWidth() * getHeight());
        bmp.UnlockBits(bmpData); //Unlock the pixels
        bmp.Save(FileName);
    }

وسؤالي هو: كيف لي أن التوجه نحو كتابة أسلوب مكافئ في C ++، باستخدام المدمج في وظائف من نظام التشغيل Windows CE 4.2

وerisu: شكرا لرمز لوحة، وأعتقد أنه صحيح. لقد لجأت إلى ملء بقية البنيات يدويا، وفقا ل صفحة ويكيبيديا .

هل كانت مفيدة؟

المحلول 2

وهذا هو الرمز الذي يعمل بالنسبة لي. لأنه يقوم على الجواب erisu و وصف ويكيبيديا من تنسيق BMP . لأي شخص آخر يستخدم هذه الإجابة، ننصحك بأن فهم تنسيق BMP على أكمل وجه ممكن، حتى تتمكن من ضبط حقول رأس وفقا لذلك.

وحلقة معقدة في النهاية هو الحل لبلدي مشكلة مع بلدي الأجهزة / OS، حيث لن إرسال كافة البيانات I تزويد fwrite. يجب أن تعمل في أي بيئة، وإن كان.

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>

#define NPAL_ENT 256

INT WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR lpCmdLine,
                    INT nShowCmd )
{
    int w = 1920, h = 1080; // My values, yours may vary

//////////////////////// File Operations ///////////////////////////////

    // Reading raw img
    FILE* f = fopen("\\FlashDisk\\raw_img.bin","r");
    if(NULL == f){printf("BAD");exit(1);}

    // Obtaining size of raw img
    fseek (f , 0L , SEEK_END);
    DWORD fsize = (DWORD)ftell (f);
    fseek (f , 0L , SEEK_SET);

    char *imgData = (char*) malloc (sizeof(char)*fsize);
    if(NULL == imgData) {printf("NOT imgData");exit(2);}

    // Copy contents of file into buffer
    DWORD result = fread(imgData,1,fsize,f);
    if (result != fsize) {
        printf ("Reading error. Expected: %d, Got: %d\n",fsize, result ); 
        if(ferror(f)){printf("An error: %d\n", ferror(f)); }
        if(feof(f)) {printf("EOF\n");}
        delete[] imgData;
        fclose(f);
        exit (3);
    }
    fclose(f);

//////////////////////// BMP Operations ///////////////////////////////

    /* A bitmap has the following components:
     *  1. BMP file header
     *  2. Bitmap Information (DIB) header
     *  3. Color Palette
     *  4. Raw Data
     */
    BITMAPFILEHEADER bmfh;
    ZeroMemory( &bmfh, sizeof( bmfh ) );
    bmfh.bfType = 0x4D42; // Magic #
    bmfh.bfSize = sizeof( bmfh ) + sizeof( BITMAPINFOHEADER )
        + NPAL_ENT*sizeof(PALETTEENTRY) + w*h; // Or total file size if w/h not known
    bmfh.bfOffBits = sizeof( bmfh ) + sizeof( BITMAPINFOHEADER )
        + NPAL_ENT*sizeof(PALETTEENTRY);

    BITMAPINFOHEADER bmih;
    ZeroMemory( &bmih, sizeof( bmih ) );
    bmih.biWidth = w;
    bmih.biHeight = h;
    bmih.biSize = sizeof(bmih);
    bmih.biPlanes = 1;
    bmih.biBitCount = 8;
    bmih.biCompression = BI_RGB;
    bmih.biSizeImage = w * h;

    int palSize = NPAL_ENT*sizeof(PALETTEENTRY);
    LOGPALETTE *logpal=(LOGPALETTE*)new BYTE[sizeof(LOGPALETTE)+palSize];
    if(!logpal) {delete [] imgData; printf("!logpal\n"); exit(4);}
    logpal->palVersion=0x300;
    logpal->palNumEntries=NPAL_ENT;
    int i=0;
    do {  // Exact palette format varies. This is what worked for me
        logpal->palPalEntry[i].peRed=i;
        logpal->palPalEntry[i].peGreen=i;
        logpal->palPalEntry[i].peBlue=i;
        logpal->palPalEntry[i].peFlags=NULL;
    } while(++i<NPAL_ENT);

    // Complete bitmap is now in memory, time to save it
    TCHAR bmpfname[80];
    wsprintf( bmpfname, (TCHAR*) TEXT( "\\USBDisk\\out.bmp" ) );

    // open the file for writing
    FILE *bmpFile = _wfopen(bmpfname,L"wb"); 
    if(!bmpFile) { delete[] imgData; delete[] logpal; exit(6); }

    // write the bitmap to file, in whatever chunks WinCE allows
    size_t totWrit = 0, offset = 0, writeAmt = 0;
    while(totWrit < bmfh.bfSize){
        if(totWrit < sizeof(bmfh)){ // File header
            offset = totWrit;
            totWrit += fwrite( ((char*)&bmfh)+offset, 1, sizeof(bmfh)-offset, bmpFile );
        }
        else if(totWrit<sizeof(bmfh)+sizeof(bmih)){ // Image header
            offset = totWrit - sizeof(bmfh);
            totWrit += fwrite( ((char*)&bmih)+offset, 1, sizeof(bmih)-offset, bmpFile );
        }
        else if(totWrit<sizeof(bmfh)+sizeof(bmih)+palSize) { // Pallette
            offset = totWrit - sizeof(bmfh) - sizeof(bmih);
            totWrit += fwrite( ((char*)&logpal->palPalEntry)+offset, 1, palSize-offset, bmpFile );
        }
        else { // Image data
            offset = totWrit - sizeof(bmfh) - sizeof(bmih) - palSize;
            if(bmfh.bfSize-totWrit >= IO_SIZE) {
                writeAmt = IO_SIZE;
            }
            else {
                writeAmt = bmfh.bfSize-totWrit;
            }
            totWrit += fwrite( &imageBuffer[offset], 1, writeAmt, bmpFile );
        }

        // Close and open after each iteration to please WinCE
        fflush(bmpFile);
        fclose(bmpFile);
        Sleep(4000); 
        bmpFile = _wfopen(bmpfname,L"ab");
        if(!bmpFile) {flog->lprintf("Couldn't reopen bmpfile"); delete [] logpal; return 0;}
    }
    fclose(bmpFile);

    if(totWrit != bmfh.bfSize) {
        printf("BMP Size mismatch: %d/%d.",totWrit,bmfh.bfSize);
        delete [] imgData;
        delete [] logpal;
        exit(-1);
    }
   // Cleanup
    delete [] imgData;
    delete [] logpal;

    return 0;

}

نصائح أخرى

وعادة ما يمكنني استخدام CreateBitmap أو CreateCompatibleBitmap لتوليد الصور النقطية في ويندوز. أنا غير مألوف مع ويندوز سي ولكن يبدو أن الوظائف التي تكون موجودة. البيانات الخاصة بك يتطلع إلى أن يكون في 8 بت لكل بكسل مع لوح ألوان 256 لذلك سوف أيضا على الأرجح بحاجة CreatePalette، SelectPalette، وظائف RealizePalette.

وشيء من هذا القبيل (تحذير: كود مجربة):

HBITMAP hBmp=CreateBitmap(width, height, 1, 8, imgData);

LOGPALETTE logpal=(LOGPALETTE)new BYTE[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
logpal.palVersion=0x300;
logpal.palNumEntries=256;
int i=0;
do {  //no idea your palette's format, however it looks to be greyscale?
    logpal->mypal[i].peRed=i;
    logpal->mypal[i].peGreen=i;
    logpal->mypal[i].peBlue=i;
    logpal->mypal[i].peFlags=NULL;
while(++i<256);
HPALETTE hPal=CreatePalette(logpal);

//If your trying to display it to a window's DC called mywindowsDC
HDC hBmpDC = CreateCompatibleDC(mywindowsDC);
SelectObject(hBmpDC, hBmp);
SelectPalette(hBmpDC, hPal, TRUE);
BitBlt(mywindowsDC, 0, 0, width, height, hBmpDC, 0, 0, SRCCOPY);
RealizePalette(mywindowsDC);
//clean up
DeleteDC(hBmpDC);
delete [](BYTE *)logpal;
DeleteObject(hPal);
DeleteObject(hBmp);

وأود أن لا قراءة في بيانات الصورة باستخدام عمليات FILE*: يمكنك ان تجعل من العمل، لكنه مطول وعرضة للمشاكل مثل fread() التفكير على Ctrl-Z يعني نهاية دورة الملفات، بالإضافة إلى أنك يجب أن نتذكر لإغلاق ملف عند الانتهاء. بدلا من ذلك فما استقاموا لكم فاستقيموا استخدام فئة CFile MFC. هذا وسوف ننظر شيء من هذا القبيل

 BYTE* pbyImageData = NULL;
CFile fileImage;
if(fileImage.Open(_T("\\rawimage.dat"), CFile::modeRead, NULL))
{
     pbyImageData = new BYTE[fileImage.GetLength()];
     fileImage.Read(pbyImageData, fileImage.GetLength());
}
يتم التعامل مع

الصور النقطية بسهولة في نظام التشغيل Windows CE باستخدام فئة CDIBSectionCE. هذا هو متاح من CodeGuru ( "A المجمع DIBSection ل Win32 وندوز "). باستخدام CDIBSectionCE، عليك أن تفعل شيئا من هذا القبيل ...

// The BITMAPINFO struct is almost completely unusable because it has
// space for a less-than-generous 1-colour palette, so I always end up
// creating a home-grown version with room for 256 colours:
struct BITMAPINFO256
{
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD          bmiColors[256];
} stcBmpInfo;

// ...Fill in the BITMAPINFO structure -- bitmap size etc.
stcBmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
stcBmpInfo.bmiHeader.biWidth = .... 
/// etc ... keep the code you have for filling in bitmap info at present

// Now load up the image into the DIB Section
CDIBSectionCE bmp;
bmp.SetBitmap((BITMAPINFO*)&stcBmpInfo, pbyImageData);

// Now write the bitmap out as a file
bmp.Save(_T("\\mybitmap.bmp");

لاحظ أن CDIBSectionCE يعالج كل الاشياء رأس الملف. كل ما عليك هو قراءة في بيانات الصورة القيام به، مجرفة قبل أن تتحول إلى مقطع DIB، ثم يطلب منها أن ينقذ نفسه من كملف النقطية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top