bmpとJpegを相互変換行うには?


Junix  2003-09-04 10:54:24  No: 52080  IP: [192.*.*.*]

Jpeg画像とBMP画像をドラッグ&ドロップで相互変換するにはどうすれば良いでしょうか?

編集 削除
pbmplus  2003-09-04 17:49:23  No: 52081  IP: [192.*.*.*]

JPEGは「DCT変換」など画像処理の特殊な知識を
必要としますので一般的にライブラリを使用して変換します。

Independent JPEG Group
http://www.ijg.org/

編集 削除
Junix  2003-09-04 18:52:55  No: 52082  IP: [192.*.*.*]

以下のソースで実行しようと思ったのですがどうしてもdib2jpg.cの部分でエラーが出てしまい回避できません。ご教授お願いします。(エラー内容:C:\Documents and Settings\Administrator\デスクトップ\bmp2jpg\dib2jpg.c(12) : error C2280: 開きカッコが({)が識別子 'jpg_save_dib_file' の前にありません。 
C:\Documents and Settings\Administrator\デスクトップ\bmp2jpg\dib2jpg.c(95) : error C2059: 構文エラー : '}'
cl.exe の実行エラー)

//dib2jpg.c
/* DIB -> JPEG 変換 (スタティックライブラリ編) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jpeglib.h"
#include "bmplib.h"

GLOBAL(int)

jpg_save_dib_file ( FILE *fp, uchar *dib, 
           int quality, int progression )
{
    int   i, j;
    int   bmp_row_bytes;
    uchar * bmp_image;
    uchar * src, * dest;
    DIB   new_dib;

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    JSAMPLE * image_buffer;
    JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
    int row_stride;               /* physical row width in image buffer */
    int image_height;
    int image_width;

    // DIB情報
    image_width = *(long  *)(dib+4);
    image_height = *(long  *)(dib+8) ;

    // 24 bit カラーに変換
    new_dib = bmp_convert_dib_24color( dib ) ;
    if( new_dib == NULL ) return FALSE;
    dib = new_dib;

    /* JPEG圧縮オブジェクトを割り当てて、初期化 */
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    jpeg_stdio_dest(&cinfo, fp);

    /* 圧縮用のパラメータを設定 */
    cinfo.image_width  = image_width;     /* イメージのピクセル幅と高さ */
    cinfo.image_height = image_height;
    cinfo.input_components = 3;           /* ピクセル当たりの色 */
    cinfo.in_color_space = JCS_RGB;       /* カラースペース */

    /* デフォルト圧縮パラメータを設定する */
    jpeg_set_defaults(&cinfo);

    /* 非デフォルトパラメータの設定 */
    jpeg_set_quality(&cinfo, quality, TRUE );

    /* Progression オプションを追加  */
    if( progression )  jpeg_simple_progression (&cinfo);

    /* 圧縮開始 */
    jpeg_start_compress(&cinfo, TRUE);

    row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
    image_buffer = malloc( row_stride );
    bmp_row_bytes = (image_width * 3 + 3) / 4 * 4;  // DWORD 境界
    bmp_image = dib + 40; // = sizeof(BITMAPINFOHEADER)

    i = image_height - 1;
    while (cinfo.next_scanline < cinfo.image_height) {
        // BMP は格納形式が上下逆。
        dest = image_buffer;
        src = &bmp_image[ i * bmp_row_bytes ];
        for( j = 0; j < image_width; j++ ) {
            *dest++ = src[ 2 ];
            *dest++ = src[ 1 ];
            *dest++ = src[ 0 ];
            src += 3;
        }
        i--;

        row_pointer[0] = image_buffer;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    /* 圧縮終了 */
    jpeg_finish_compress(&cinfo);

    /* JPEG 圧縮オブジェクトの開放 */
    jpeg_destroy_compress(&cinfo);

    free( image_buffer );
    image_buffer = 0;
    free( new_dib );
    return( TRUE );
}

//bmp2jpg.c
/*   BMP -> JPEG ファイル変換 */

#include <stdio.h>
#include <string.h>
#include "jpeglib.h"
#include "bmplib.h"

#define MAX_PATH 270

int main( int argc, char *argv[] ) {
    int  arg_cou = 0, i;
    int  quality = 90;
    int  progression = 0;
    char *w_ptr;
    char inpfile[ MAX_PATH ];
    char outfile[ MAX_PATH ];
    FILE  *fp;
    DIB  dib;

    for( i = 1; i < argc; i++ ) {
        w_ptr = argv[ i ];
        if( *w_ptr == '/' || *w_ptr == '-' ) {
            int  c;
            w_ptr++;
            c = toupper( *w_ptr++ );
            if( *w_ptr == '=' ) w_ptr++;
            switch( c ) {
              case 'Q':
                quality = atoi( w_ptr );
                break;
              case 'P':
                progression = TRUE;
                break;
              default:
                printf( "option (%c) is nothing!\n", c );
                break;
            }
            continue;
        }
        arg_cou++;
        if( arg_cou == 1 ) {
            strcpy( inpfile, w_ptr );
            continue;
        }
        if( arg_cou == 2 ) {
            strcpy( outfile, w_ptr );
            continue;
        }
    }

    if( arg_cou < 1 ) {
        printf( "\n\t>bmp2jpg input_file[.bmp] [output_file[.jpg]] [-Qnnn)][-P]\n\n");
        printf( "\t\t-P ... Progression\n");
        printf( "\t\t-Q ... Quality nnn:0〜100(default=90)\n\n");
        exit(0);
    }

    if( ( w_ptr = strchr( inpfile, '.' ) ) == 0 ) {
        strcat( inpfile, ".bmp" );
    }

    if( arg_cou < 2 ) {
       strcpy( outfile, inpfile );
       if( w_ptr = strchr( outfile, '.' ) ) *w_ptr = 0;
    }
    if( ( w_ptr = strchr( outfile, '.' ) ) == 0 ) {
       strcat( outfile, ".jpg" );
    }

    if( ( fp = fopen( inpfile, "rb" ) ) == 0 ) {
        printf( "input file (%s) not open!\n", inpfile );
        exit(1);
    }

    // BMP ファイルを読み込み、DIB を作成
    if( ( dib = bmp_read_dib_file( fp ) ) == NULL ) {
        fclose( fp );
        printf( "BMP file read error!\n" );
        exit(1);
    }
    fclose( fp );

    // biBitCount が 24 bit カラー以外なら変換
    if( *(DWORD *)(dib+14) != 24 && *(DWORD *)(dib+14) == 0 ) {
        DIB new_dib;
        if( ( new_dib = bmp_convert_dib_24color( dib ) ) == NULL ) {
            printf( "BMP format not support!\n" );
            exit(1);
        }
        free( dib );
        dib = new_dib;
    }

    // JPEG ファイルへの書き出し操作
    //   「上書き」の検査が必要ならコードを追加して下さい
    if( ( fp = fopen( outfile, "wb" ) ) == 0 ) {
        printf( "output file (%s) not open!\n", outfile );
        exit(1);
    }

    if( jpg_save_dib_file( fp, dib, quality, progression ) == FALSE ) {
        printf( "output JPEG file error!\n" );
    }
    fclose( fp );
    free( dib );
}

//bmplib.h
#ifndef BITMAPINFOHEADER

/* 以下は、windows.h より */

#define TRUE  1
#define FALSE 0

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef long LONG;

typedef struct tagRGBQUAD {
    BYTE    rgbBlue;
    BYTE    rgbGreen;
    BYTE    rgbRed;
    BYTE    rgbReserved;
} RGBQUAD;

// DLL 化のオプション
#ifndef EXPORT_OPTION

#ifdef MAKEVBDLL
#define EXPORT_OPTION __declspec(dllexport) __stdcall
#define MAKEDLL
#else
#ifdef MAKEDLL
#define EXPORT_OPTION __declspec(dllexport)
#else
#define EXPORT_OPTION
#endif
#endif

#endif

/* constants for the biCompression field */
#define BI_RGB        0L
#define BI_RLE8       1L
#define BI_RLE4       2L
#define BI_BITFIELDS  3L

typedef struct tagBITMAPFILEHEADER {
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
    DWORD      biSize;
    LONG       biWidth;
    LONG       biHeight;
    WORD       biPlanes;
    WORD       biBitCount;
    DWORD      biCompression;
    DWORD      biSizeImage;
    LONG       biXPelsPerMeter;
    LONG       biYPelsPerMeter;
    DWORD      biClrUsed;
    DWORD      biClrImportant;
} BITMAPINFOHEADER;

#endif

/* 以下は独自の定義 */

typedef unsigned char uchar;
typedef unsigned int  uint;
typedef char * DIB;


DIB bmp_read_dib_file( FILE *fp ) ;
DIB bmp_read_dib_filename( char *filename ) ;
int bmp_save_dib_file( FILE *fp, DIB dib ) ;
int bmp_save_dib_filename( char *filename, DIB dib ) ;
DIB bmp_expand_dib_rle( DIB dib ) ;
DIB bmp_compress_dib_rle( DIB dib );
DIB bmp_convert_dib_24color( DIB dib ); 

//jpeglib.h
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
/* see jconfig.doc for explanations */

#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS  /* we presume a 32-bit flat memory model */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN

/* Define "boolean" as unsigned char, not int, per Windows custom */
#ifndef __RPCNDR_H__    /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN    /* prevent jmorecfg.h from redefining it */


#ifdef JPEG_INTERNALS

#undef RIGHT_SHIFT_IS_UNSIGNED

#endif /* JPEG_INTERNALS */

#ifdef JPEG_CJPEG_DJPEG

#define BMP_SUPPORTED    /* BMP image file format */
#define GIF_SUPPORTED    /* GIF image file format */
#define PPM_SUPPORTED    /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED    /* Utah RLE image file format */
#define TARGA_SUPPORTED    /* Targa image file format */

#define TWO_FILE_COMMANDLINE  /* optional */
#define USE_SETMODE    /* Microsoft has setmode() */
#undef NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT    /* optional */

#endif /* JPEG_CJPEG_DJPEG */

編集 削除
Junix  2003-09-09 08:44:34  No: 52083  IP: [192.*.*.*]

ライブラリを使用しないでbmpのイメージデータを抽出しDCT変換等を駆使してbmpからjpegの片方向変換を行いたいのですが、bmpのイメージデータを抽出できても
その後の方法が皆目検討がつきません。どなたか、ご教授お願いいたします。

編集 削除