सी

2012-06-12 12 views
14

में एक बीएमपी फ़ाइल (बिटमैप) बनाना, मैं केवल कोड से सी में बिटमैप बनाने की कोशिश कर रहा हूं। मैं वर्तमान में सभी सफेद पिक्सेल के साथ 1px की ऊंचाई और 4 पिक्सेल की चौड़ाई के साथ एक बहुत ही आसान .bmp छवि बनाने की कोशिश कर रहा हूं। मैंने प्रारूप विवरण पढ़ा है और इसे लागू करने का प्रयास किया है। यह निम्न कोड में हुई:सी

char bitmap[1000]; 

void BMPmake() 
{ 
    // -- FILE HEADER -- // 

    // bitmap signature 
    bitmap[0] = 'B'; 
    bitmap[1] = 'M'; 

    // file size 
    bitmap[2] = 66; // 40 + 14 + 12 
    bitmap[3] = 0; 
    bitmap[4] = 0; 
    bitmap[5] = 0; 

    // reserved field (in hex. 00 00 00 00) 
    for(int i = 6; i < 10; i++) bitmap[i] = 0; 

    // offset of pixel data inside the image 
    for(int i = 10; i < 14; i++) bitmap[i] = 0; 

    // -- BITMAP HEADER -- // 

    // header size 
    bitmap[14] = 40; 
    for(int i = 15; i < 18; i++) bitmap[i] = 0; 

    // width of the image 
    bitmap[18] = 4; 
    for(int i = 19; i < 22; i++) bitmap[i] = 0; 

    // height of the image 
    bitmap[22] = 1; 
    for(int i = 23; i < 26; i++) bitmap[i] = 0; 

    // reserved field 
    bitmap[26] = 1; 
    bitmap[27] = 0; 

    // number of bits per pixel 
    bitmap[28] = 24; // 3 byte 
    bitmap[29] = 0; 

    // compression method (no compression here) 
    for(int i = 30; i < 34; i++) bitmap[i] = 0; 

    // size of pixel data 
    bitmap[34] = 12; // 12 bits => 4 pixels 
    bitmap[35] = 0; 
    bitmap[36] = 0; 
    bitmap[37] = 0; 

    // horizontal resolution of the image - pixels per meter (2835) 
    bitmap[38] = 0; 
    bitmap[39] = 0; 
    bitmap[40] = 0b00110000; 
    bitmap[41] = 0b10110001; 

    // vertical resolution of the image - pixels per meter (2835) 
    bitmap[42] = 0; 
    bitmap[43] = 0; 
    bitmap[44] = 0b00110000; 
    bitmap[45] = 0b10110001; 

    // color pallette information 
    for(int i = 46; i < 50; i++) bitmap[i] = 0; 

    // number of important colors 
    for(int i = 50; i < 54; i++) bitmap[i] = 0; 

    // -- PIXEL DATA -- // 
    for(int i = 54; i < 66; i++) bitmap[i] = 0; 
} 

void BMPwrite() 
{ 
    FILE *file; 
    file = fopen("bitmap.bmp", "w+"); 
    for(int i = 0; i < 66; i++) 
    { 
     fputc(bitmap[i], file); 
    } 
    fclose(file); 
} 

जब मैं इस छवि को खोलने का प्रयास है, यह कहना है कि छवि क्षतिग्रस्त है। क्या मुझसे कोई चूक हो रही है?

मैंने यह भी देखा कि .bmp पूर्णांक का एन्कोडिंग थोड़ा अंतराल है। मैंने सोचा कि इसका मतलब है कि मुझे बाइट्स के क्रम को पीछे हटाना है। उदाहरण के लिए, चार बाइट्स में 256 है: 00000000 00000000 00000001 00000000, और मुझे लगता है कि थोड़ा एंडियन में यह होगा: 00000000 00000001 00000000 00000000

क्या कोई मुझे यहां एक हाथ दे सकता है? क्या मैं सही दृष्टिकोण का उपयोग कर रहा हूं? किसी भी सहायता की सराहना की जाएगी!

अग्रिम धन्यवाद!

+3

एक ऐसी छवि बनाएं जिसे आप अपने पसंदीदा ग्राफिक संपादक का उपयोग करके जेनरेट करना चाहते हैं, और फिर इसे बाइट-फॉर-बाइट को दोहराने का प्रयास करें। – dasblinkenlight

+0

आपको संकल्प फ़ील्ड पर अंतहीनता मिली है। यदि आप 2-बाइट और 4-बाइट पूर्णांक लेने के लिए सहायक कार्यों को लिखते हैं और उन्हें आपके बाइट सरणी में पैक करते हैं तो आपको अपना काम अधिक आसान लगेगा। –

+0

dasblinkenlight, मैंने पिक्सेलमेटर (मैक पर) करने की कोशिश की है, लेकिन मुझे 84 बाइट्स की एक बीएमपी फ़ाइल मिली है, जबकि मुझे उम्मीद है कि यह 66 बाइट्स हो, शायद मैं इसे एक प्रोग्राम के साथ खोलने का प्रयास कर सकता हूं जो मुझे बाइट प्रति दिखाता है बाइट;) – Devos50

उत्तर

8

आपका पिक्सेल ऑफसेट (बाइट्स 10..13) शून्य है, लेकिन वास्तव में पिक्सेल डेटा फ़ाइल की शुरुआत में शुरू नहीं करते हैं, वे 54

इसके अलावा बाइट पर शुरू:

  • बाइट 34 पर आपकी टिप्पणी "बिट्स" कहती है लेकिन इसका मतलब है "बाइट्स", लेकिन निश्चित रूप से इससे कोई फर्क नहीं पड़ता।

  • आपके क्षैतिज और लंबवत संकल्पों में गलत बाइट ऑर्डर है, लेकिन मुझे बहुत संदेह है कि यह महत्वपूर्ण है।

यदि मैं यह कर रहे थे मैं हैडर डेटा के लिए structs निर्धारित करेंगे (वास्तव में, यदि आप Windows पर हैं, माइक्रोसॉफ्ट पहले से ही यह किया है) और सही क्रम में बाइट्स डालने के लिए कोई मैक्रो या कुछ का उपयोग portably।

चाहे आपको "बाइट्स के क्रम को उलटना है" आप जिस प्रोसेसर का उपयोग कर रहे हैं उसकी अंतहीनता पर निर्भर करता है। अलग-अलग बाइट्स को अलग से लिखना, जैसा कि आप कर रहे हैं, इस बारे में चिंता करने से बचने का एक प्रभावी तरीका है।

+0

आह का हिस्सा नहीं है, इसलिए आप कह रहे हैं कि ऑफ़सेट फ़ाइल की शुरुआत के बीच बाइट्स की संख्या है और पिक्सेल डेटा की शुरुआत? तो इस मामले में यह 54 बाइट्स (फ़ाइल हेडर के लिए 14 बाइट्स और बिटमैप हेडर के लिए 40) होगा? – Devos50

+0

मुझे अब यह काम मिल गया है! समस्या वास्तव में पिक्सेल ऑफसेट के साथ थी, मैंने इसे 54 कर दिया है और अब मैं बिटमैप खोल सकता हूं! उनकी मदद के लिए सभी को धन्यवाद :) – Devos50

+0

सही।[इस नोट को अनदेखा करें - यह केवल कुछ अतिरिक्त पाठ है क्योंकि स्टैक ओवरफ़्लो बहुत कम टिप्पणियों की अनुमति नहीं देता है।] –

3

वास्तव में वहां क्या है यह देखने के लिए अपनी फ़ाइल को हेक्स संपादक के साथ खोलें। यह आपको यह निर्धारित करने में मदद करेगा कि आपका कोड अप्रत्याशित कुछ कर रहा है या नहीं।

+0

निश्चित रूप से उस कल कोशिश करने जा रहा है! सलाह के लिये धन्यवाद! – Devos50

+1

बीटीडब्ल्यू, आप फ़ाइल को "wb +" (बाइनरी) मोड में खोलना चाहेंगे। – jdigital

4

यहां लिनक्स पर परीक्षण कोड है।

#include <stdio.h> 
#include <stdint.h> 
#include <string.h> 
#include <malloc.h> 
#define _height 600 
#define _width 800 
#define _bitsperpixel 24 
#define _planes 1 
#define _compression 0 
#define _pixelbytesize _height*_width*_bitsperpixel/8 
#define _filesize _pixelbytesize+sizeof(bitmap) 
#define _xpixelpermeter 0x130B //2835 , 72 DPI 
#define _ypixelpermeter 0x130B //2835 , 72 DPI 
#define pixel 0xFF 
#pragma pack(push,1) 
typedef struct{ 
    uint8_t signature[2]; 
    uint32_t filesize; 
    uint32_t reserved; 
    uint32_t fileoffset_to_pixelarray; 
} fileheader; 
typedef struct{ 
    uint32_t dibheadersize; 
    uint32_t width; 
    uint32_t height; 
    uint16_t planes; 
    uint16_t bitsperpixel; 
    uint32_t compression; 
    uint32_t imagesize; 
    uint32_t ypixelpermeter; 
    uint32_t xpixelpermeter; 
    uint32_t numcolorspallette; 
    uint32_t mostimpcolor; 
} bitmapinfoheader; 
typedef struct { 
    fileheader fileheader; 
    bitmapinfoheader bitmapinfoheader; 
} bitmap; 
#pragma pack(pop) 

int main (int argc , char *argv[]) { 
    FILE *fp = fopen("test.bmp","wb"); 
    bitmap *pbitmap = (bitmap*)calloc(1,sizeof(bitmap)); 
    uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize); 
    strcpy(pbitmap->fileheader.signature,"BM"); 
    pbitmap->fileheader.filesize = _filesize; 
    pbitmap->fileheader.fileoffset_to_pixelarray = sizeof(bitmap); 
    pbitmap->bitmapinfoheader.dibheadersize =sizeof(bitmapinfoheader); 
    pbitmap->bitmapinfoheader.width = _width; 
    pbitmap->bitmapinfoheader.height = _height; 
    pbitmap->bitmapinfoheader.planes = _planes; 
    pbitmap->bitmapinfoheader.bitsperpixel = _bitsperpixel; 
    pbitmap->bitmapinfoheader.compression = _compression; 
    pbitmap->bitmapinfoheader.imagesize = _pixelbytesize; 
    pbitmap->bitmapinfoheader.ypixelpermeter = _ypixelpermeter ; 
    pbitmap->bitmapinfoheader.xpixelpermeter = _xpixelpermeter ; 
    pbitmap->bitmapinfoheader.numcolorspallette = 0; 
    fwrite (pbitmap, 1, sizeof(bitmap),fp); 
    memset(pixelbuffer,pixel,_pixelbytesize); 
    fwrite(pixelbuffer,1,_pixelbytesize,fp); 
    fclose(fp); 
    free(pbitmap); 
    free(pixelbuffer); 
} 
+0

यह मानता है कि आपकी मूल उन्मूलन विंडोज़ (बीएमपी फ़ाइल प्रारूप का उत्प्रेरक) जैसा ही है। "लिनक्स पर परीक्षण" संभावित अंतहीनता के मुद्दों के बारे में कुछ भी नहीं बताता है। – usr2564301

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^