2012-01-11 10 views
6

मैं 16-बिट ग्रेस्केल छवि लिखने की कोशिश कर रहा हूं जहां प्रत्येक बिंदु रंग इसके निर्देशांक के बराबर होता है। निम्नलिखित कोड को 16-बिट पीएनजी उत्पन्न करना चाहिए, लेकिन इसके बजाय 8-बिट this उत्पन्न करता है। क्यूं कर?16 बिट ग्रेस्केल पीएनजी

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <png.h> 

void save_png(FILE* fp, long int size) 
{ 
    png_structp png_ptr = NULL; 
    png_infop info_ptr = NULL; 
    size_t x, y; 
    png_bytepp row_pointers; 

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
    if (png_ptr == NULL) { 
     return ; 
    } 

    info_ptr = png_create_info_struct(png_ptr); 
    if (info_ptr == NULL) { 
     png_destroy_write_struct(&png_ptr, NULL); 
     return ; 
    } 

    if (setjmp(png_jmpbuf(png_ptr))) { 
     png_destroy_write_struct(&png_ptr, &info_ptr); 
     return ; 
    } 

    png_set_IHDR(png_ptr, info_ptr, 
       size, size, // width and height 
       16, // bit depth 
       PNG_COLOR_TYPE_GRAY, // color type 
       PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 

    /* Initialize rows of PNG. */ 
    row_pointers = (png_bytepp)png_malloc(png_ptr, 
     size*png_sizeof(png_bytep)); 

    for (int i=0; i<size; i++) 
     row_pointers[i]=NULL; 

    for (int i=0; i<size; i++) 
     row_pointers[i]=png_malloc(png_ptr, size*2); 

    //set row data 
    for (y = 0; y < size; ++y) { 
     png_bytep row = row_pointers[y]; 
     for (x = 0; x < size; ++x) { 
       short color = x+y; 
       *row++ = (png_byte)(color & 0xFF); 
       *row++ = (png_byte)(color >> 8); 
     } 
    } 

    /* Actually write the image data. */ 
    png_init_io(png_ptr, fp); 
    png_set_rows(png_ptr, info_ptr, row_pointers); 
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 
    //png_write_image(png_ptr, row_pointers); 

    /* Cleanup. */ 
    for (y = 0; y < size; y++) { 
     png_free(png_ptr, row_pointers[y]); 
    } 
    png_free(png_ptr, row_pointers); 
    png_destroy_write_struct(&png_ptr, &info_ptr); 
} 

int main() 
{ 
    FILE* f; 
    if((f=fopen("test.png", "wb"))!=NULL) 
    { 
    save_png(f, 257); 

    fclose(f); 
    } 
    return 0; 
} 

उत्तर

5

लिंक्ड करने के लिए छवि जा रहा है "16-बिट" विंडोज 7 के "गुण" के रूप में दिखाता है। मुझे लगता है कि आप डिस्प्ले के लिए 8-बिट में परिवर्तित करने के लिए वापस आने वाले विभिन्न एप्लिकेशन देख रहे हैं, जो (मुझे लगता है) बहुत उम्मीद है क्योंकि अधिकांश डिस्प्ले डिवाइस 16 बिट्स का समर्थन नहीं करते हैं।

+0

विंडोज 7 दो ढाल-भरे त्रिकोण दिखाता है। यह 8-बिट के लिए 16-बिट छवि और त्रिकोण के लिए एक वर्ग होना चाहिए। – Yagg

+0

ओह, आप सही हैं। मैंने libpng के साथ छवि को फिर से पढ़ा और बिंदु के रंगों का परीक्षण किया। वे जैसे होना चाहिए। – Yagg

1

पुराने धागे को पुनर्जीवित करने के लिए खेद है, लेकिन मैं 16 बिट ग्रेस्केल छवियों को लिखने के लिए googling के बाद यहां आया। मैं इसी तरह की समस्याओं में भाग गया, और मैंने सोचा कि यह पोस्ट करना सहायक होगा कि मैंने इस मुद्दे को कैसे हल किया।

टी एल; डॉ:

क) बाइट्स पहले पुस्तकालय MSB के लिए उपलब्ध कराया जाना है, तो यह काम करता है अगर आप इस के लिए ऊपर लाइनों फ्लिप:

*row++ = (png_byte)(color >> 8); 
*row++ = (png_byte)(color & 0xFF); 

ख) वास्तव में देखने के लिए 8-बिट स्क्रीन पर 16 बिट मान, 256 के तहत किसी भी मान को केवल काले रंग में फिसल जाएगा। व्यावहारिक रूप से बोलते हुए, मूल्य जो कि 256 के कई गुणक हैं, कुछ भी देखने के लिए इस्तेमाल किया जाना चाहिए। ऊपर वर्णित रंग = एक्स + वाई कोड ने उन मूल्यों का उत्पादन नहीं किया जो पर्याप्त उज्ज्वल थे।

कैसे मैं ऊपर निष्कर्ष पर मिल गया:

मैं ऊपर कोड के साथ शुरू कर दिया, केवल 'एक्स' रंग के रूप में, 'x + y' नहीं इस्तेमाल करते हैं।

इरादा एक ढाल होना था जो बाएं से काले रंग में फीका हुआ था, जो कि अधिकतम x दाईं ओर था।

हालांकि, एक लंबे ढाल के बजाय, मुझे इसके बजाय कई संकीर्ण ग्रेडियेंट मिल रहे थे। यह चिल्लाया "गलत अंतहीनता!"

मैंने बिट्स को बदलने की कोशिश की, लेकिन फिर मुझे एक काला छवि मिली। मुझे थोड़ी देर लग गई, लेकिन स्क्रीन केवल 8 बिट्स में प्रदर्शित होती है, यहां तक ​​कि अधिकतम मूल्य (मेरे मामले में) 968 बहुत अंधेरा था। यह 8 बिट स्क्रीन पर 2 या 3 तक मैप करता है, और यहां तक ​​कि उच्च गामा के साथ मैं अंतर नहीं देख पा रहा था।

चूंकि मुझे पता था कि मेरा अधिकतम एक्स लगभग 1000 था, और 16 बिट मान के लिए अधिकतम मूल्य 65000 आइस है, इसलिए मैंने अपने रंग के रूप में (x * 60) का उपयोग किया। यह एक दृश्य परिणाम का उत्पादन समाप्त हो गया।

मूल पोस्ट के लिए धन्यवाद। शुरू करने के लिए यह एक उत्कृष्ट उदाहरण था।

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