2014-03-28 24 views
-1

如何正确地将bmp转换为png?我用这个代码:将bmp转换为png - 访问冲突写入位置

#define WIN32_LEAN_AND_MEAN 
#define _CRT_SECURE_NO_DEPRECATE 

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

void GetDesktopResolution(int& horizontal, int& vertical) 
{ 
    RECT desktop; 
    // Get a handle to the desktop window 
    const HWND hDesktop = GetDesktopWindow(); 
    // Get the size of screen to the variable desktop 
    GetWindowRect(hDesktop, &desktop); 
    // The top left corner will have coordinates (0,0) 
    // and the bottom right corner will have coordinates 
    // (horizontal, vertical) 
    horizontal = desktop.right; 
    vertical = desktop.bottom; 
} 

typedef struct _RGBPixel { 
    uint8_t blue; 
    uint8_t green; 
    uint8_t red; 
} RGBPixel; 

/* Structure for containing decompressed bitmaps. */ 
typedef struct _RGBBitmap { 
    RGBPixel *pixels; 
    size_t width; 
    size_t height; 
    size_t bytewidth; 
    uint8_t bytes_per_pixel; 
} RGBBitmap; 

/* Returns pixel of bitmap at given point. */ 
#define RGBPixelAtPoint(image, x, y) \ 
    *(((image)->pixels) + (((image)->bytewidth * (y)) \ 
         + ((x) * (image)->bytes_per_pixel))) 

/* Attempts to save PNG to file; returns 0 on success, non-zero on error. */ 
int save_png_to_file(RGBBitmap *bitmap, const char *path) 
{ 
    FILE *fp = fopen(path, "wb"); 
    png_structp png_ptr = NULL; 
    png_infop info_ptr = NULL; 
    size_t x, y; 
    png_uint_32 bytes_per_row; 
    png_byte **row_pointers = NULL; 

    if (fp == NULL) return -1; 

    /* Initialize the write struct. */ 
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
    if (png_ptr == NULL) { 
     fclose(fp); 
     return -1; 
    } 

    /* Initialize the info struct. */ 
    info_ptr = png_create_info_struct(png_ptr); 
    if (info_ptr == NULL) { 
     png_destroy_write_struct(&png_ptr, NULL); 
     fclose(fp); 
     return -1; 
    } 

    /* Set up error handling. */ 
    if (setjmp(png_jmpbuf(png_ptr))) { 
     png_destroy_write_struct(&png_ptr, &info_ptr); 
     fclose(fp); 
     return -1; 
    } 

    /* Set image attributes. */ 
    png_set_IHDR(png_ptr, 
       info_ptr, 
       bitmap->width, 
       bitmap->height, 
       8, 
       PNG_COLOR_TYPE_RGB, 
       PNG_INTERLACE_NONE, 
       PNG_COMPRESSION_TYPE_DEFAULT, 
       PNG_FILTER_TYPE_DEFAULT); 

    /* Initialize rows of PNG. */ 
    bytes_per_row = bitmap->width * bitmap->bytes_per_pixel; 
    png_malloc(png_ptr, bitmap->height * sizeof(png_byte *)); 
    for (y = 0; y < bitmap->height; ++y) { 
     uint8_t *row = (uint8_t *)png_malloc(png_ptr, sizeof(uint8_t)* bitmap->bytes_per_pixel); 
     row_pointers[y] = (png_byte *)row; /************* MARKED LINE ***************/ 
     for (x = 0; x < bitmap->width; ++x) { 
      RGBPixel color = RGBPixelAtPoint(bitmap, x, y); 
      *row++ = color.red; 
      *row++ = color.green; 
      *row++ = color.blue; 
     } 
    } 

    /* 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); 

    /* Cleanup. */ 
    for (y = 0; y < bitmap->height; y++) { 
     png_free(png_ptr, row_pointers[y]); 
    } 
    png_free(png_ptr, row_pointers); 

    /* Finish writing. */ 
    png_destroy_write_struct(&png_ptr, &info_ptr); 
    fclose(fp); 
    return 0; 
} 

int main() 
{ 
     RGBBitmap rgbbitmap; 
    int w, h; 
    GetDesktopResolution(w, h); 
    rgbbitmap.height = h; 
    rgbbitmap.width = w; 
    rgbbitmap.bytes_per_pixel = 1; 
    rgbbitmap.bytewidth = w/100; 

    RGBPixel rgbpixel; 
    rgbpixel.blue = 100; 
    rgbpixel.green = 100; 
    rgbpixel.red = 100; 
    rgbbitmap.pixels = &rgbpixel; 

    save_png_to_file(&rgbbitmap, "abc.bmp"); 

     return 0; 
} 

但在运行时,我得到的标线这个错误:

在0x01258F04在ProjectName.exe

未处理的异常:0000005:访问冲突写入位置00000000 。

我在网上搜索过,我找到了this interesting small code,但是我没能找到它的母亲lib。而且,我认为使用libpng可以更好地控制输出图像。

如何解决此问题?或者,也许这是一种错误的转换方式?如果是这样,我该怎么做?

回答

2

你永远不会为row_pointers分配内存,所以当你做row_pointers[y] = (png_byte *)row;时它是NULL

+0

感谢您的回答,请您告诉我如何正确初始化它? – user3471387

+0

@ user3471387你已经* do *分配这个内存,你只是不要将它分配给'row_pointers'。查看'for'循环上方的'png_malloc'调用。 –

+0

@ user3471387您应该将此作为一个教训,在真正理解代码的作用之前,不要盲目复制和使用其他人的代码。实际上,如果代码中隐藏了某种特洛伊木马,会发生什么? –