掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
MFCを使ってPDFファイルにJPEG画像を組み込むには? (ID:51767)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
非常に雑ですが8bitと24bitのビットマップを PDFファイルに変換できるようにいじってみました。試してみてください。 // BMP2PDF (8bit/24bitのみ対応) #include <stdio.h> #include <malloc.h> #include <string.h> #include <stdlib.h> typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; #define FALSE 0 #define TRUE 1 BOOL GetBMPSize(FILE *BMPStream,long *offset); void Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],int Count); void Write_ContentsObject(FILE *AStream,DWORD ObjectPosArray[],int *ObjectIndex,int w,int h); int BMPtoPDF(const char *OpenName,const char *SaveName); int main(int argc,char *argv[]) { if (argc >= 2) return (BMPtoPDF(argv[1],"c:\\bmppdf.pdf")); else { printf("Not Found!\n"); return(0); } } /* 1ラインの幅を算出 */ int GetLineWidth(WORD biBitCount, int biWidth) { return ((biBitCount * biWidth + 15) / 16) * 2 ; } /* イメージデータのサイズを算出 */ int GetBitsSize(int biWidth, int biHeight,WORD biBitCount) { switch (biBitCount) { case 1: return ( ((1 * biWidth + 15) / 16) * 2 * (biHeight) );break; case 4: return ( ((4 * biWidth + 15) / 16) * 2 * (biHeight) );break; case 8: return ( biWidth*biHeight ) ;break; case 24: return ( biWidth*biHeight*3 );break; default : return ( 0 );break; } } /* イメージデータの取得 */ BOOL GetBitsData(FILE *AStream,int bfOffBits,BYTE *BitsData, int biWidth, int biHeight,WORD biBitCount) { int i; BYTE Dummy[4],DummyCnt; fseek(AStream,bfOffBits,SEEK_SET); switch (biBitCount) { case 1:; case 4:; case 8: DummyCnt= biWidth % 4; switch (DummyCnt) { case 0: for (i=0;i< biHeight;i++) fread(BitsData+(biWidth*i),1,biWidth,AStream); break; case 1 :; case 2 :; case 3 :; for (i=0;i< biHeight;i++) { fread(BitsData+(biWidth*i),1,biWidth,AStream); fread(Dummy,1,4-DummyCnt,AStream); } break; default: return (FALSE); } break; ;break; case 24: DummyCnt= biWidth % 4; switch (DummyCnt) { case 0: for (i=0;i< biHeight;i++) fread(BitsData+(biWidth*3*i),1,biWidth*3,AStream); break; case 1 :; case 2 :; case 3 : for (i=0;i< biHeight;i++) { fread(BitsData+(biWidth*3*i),1,biWidth*3,AStream); fread(Dummy,1,DummyCnt,AStream); } break; default: return (FALSE); } break; } return (TRUE); } /* イメージデータを反転させる */ BOOL TurnBits(BYTE *BitsData,int BitsSize,int biWidth,WORD biBitCount) { int i,j,LineWidth=0; BYTE *buffer,*Linebuffer,tmp; // 1ラインの幅を算出 switch (biBitCount) { case 1: ; case 4: LineWidth=GetLineWidth(biBitCount,biWidth);break; case 8: LineWidth=biWidth; break; case 24: LineWidth=biWidth*3;break; } Linebuffer=(BYTE *)malloc(LineWidth); if (Linebuffer==NULL) return FALSE; buffer=(BYTE *)malloc(BitsSize); if (buffer==NULL) { free(Linebuffer); return FALSE; } if (biBitCount==24) { for (i=0;i< (BitsSize / LineWidth);i++) { /* 1ラインを取得 */ memcpy(Linebuffer,BitsData+(LineWidth*i),LineWidth); /* BGR<->RGB変換 */ for (j=0;j<LineWidth ;j+=3) { tmp = Linebuffer[j]; Linebuffer[j] = Linebuffer[j+2]; Linebuffer[j+2] = tmp; } /* 1ラインをメモリに書き込む */ memcpy(buffer+ (BitsSize- LineWidth * (i+1) ),Linebuffer,LineWidth); } } else { for (i=0;i< (BitsSize / LineWidth);i++) { /* 1ラインを取得 */ memcpy(Linebuffer,BitsData+(LineWidth*i),LineWidth); /* 1ラインをメモリに書き込む */ memcpy(buffer+ (BitsSize- LineWidth * (i+1) ),Linebuffer,LineWidth); } } // 元のデータと置き換える memcpy(BitsData,buffer,BitsSize); free(buffer); free(Linebuffer); return(TRUE); } BOOL GetBMPSize(FILE *BMPStream,long *offset) { //WORD wrk; //BYTE Sampling; //WORD SOF0 =0xFFC0; /* 通常 */ //WORD SOF2 =0xFFC2; /* 進歩 */ /*----------------------------*/ /* ファイルヘッダ部 (14 Byte) */ /*----------------------------*/ int count = 0; long var_long; short var_short; char s[10]; // BITMAP 認識文字 "BM" if (fread(s, 2, 1, BMPStream) == 1) { if (memcmp(s, "BM", 2) == 0) { printf("[BM] BITMAP file\n"); } else { fprintf(stderr, "%s : Not a BITMAP file\n", s); exit(1); } count += 2; } printf(" [BITMAPFILEHEADER]\n"); // ファイルサイズ if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" Size : %ld [Byte]\n", var_long); count += 4; } // 予約領域 0 if (fread(&var_short, 2, 1, BMPStream) == 1) { count += 2; } // 予約領域 0 if (fread(&var_short, 2, 1, BMPStream) == 1) { count += 2; } // ファイルの先頭から画像データまでの位置 if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" OffBits : %ld [Byte]\n", var_long); *offset = var_long; count += 4; } return count; } /*------------------------------------------------------------------*/ /* 情報ヘッダ部 (12 Byte -> OS/2 Bitmap, 40 Byte -> Windows Bitmap) */ /*------------------------------------------------------------------*/ int infoheader(FILE *BMPStream, short *infosize, long *width, long *height, long *x_coodinate, long *y_coodinate, short *BitCount, long *ClrUsed) { int count = 0; long var_long, compress = 0; short var_short; // BITMAPINFOHEADER のサイズ if (fread(&var_long, 4, 1, BMPStream) == 1) { count += 4; *infosize = var_long; } printf(" [BITMAPINFOHEADER]\n"); // OS/2 Bitmap if (*infosize == 12) { // 画像データの幅 if (fread(&var_short, 2, 1, BMPStream) == 1) { printf(" Width : %d [pixel]\n", var_short); *width = var_short; count += 2; } // 画像データの高さ if (fread(&var_short, 2, 1, BMPStream) == 1) { printf(" Height : %d [pixel]\n", var_short); *height = var_short; count += 2; } // プレーン数 (1のみ) if (fread(&var_short, 2, 1, BMPStream) == 1) { count += 2; } // 1画素あたりのビット数 (1, 4, 8, 24, 32) if (fread(&var_short, 2, 1, BMPStream) == 1) { printf(" BitCount : %d [bit]\n", var_short); *BitCount = var_short; count += 2; } } // Windows BMP else if (*infosize == 40) { // 画像データの幅 if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" Width : %ld [pixel]\n", var_long); *width = var_long; count += 4; } // 画像データの高さ if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" Height : %ld [pixel]\n", var_long); *height = var_long; count += 4; } // プレーン数 (1のみ) if (fread(&var_short, 2, 1, BMPStream) == 1) { count += 2; } // 1画素あたりのビット数 (1, 4, 8, 24, 32) if (fread(&var_short, 2, 1, BMPStream) == 1) { printf(" BitCount : %d [bit]\n", var_short); *BitCount = var_short; count += 2; } // 圧縮方式 0 : 無圧縮 // 1 : BI_RLE8 8bit RunLength 圧縮 // 2 : BI_RLE4 4bit RunLength 圧縮 if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" Compression : %ld\n", var_long); compress = var_long; count += 4; } // 画像データのサイズ if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" SizeImage : %ld [Byte]\n", var_long); count += 4; } // 横方向解像度 (Pixel/meter) if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" XPelsPerMeter : %ld [pixel/m]\n", var_long); *x_coodinate = var_long; count += 4; } // 縦方向解像度 (Pixel/meter) if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" YPelsPerMeter : %ld [pixel/m]\n", var_long); *y_coodinate = var_long; count += 4; } // 使用色数 if (fread(&var_long, 4, 1, BMPStream) == 1) { printf(" ClrUsed : %ld [color]\n", var_long); *ClrUsed = var_long; count += 4; } // 重要な色の数 0の場合すべての色 if (fread(&var_long, 4, 1, BMPStream) == 1) { count += 4; } } else { fprintf(stderr, "Bitmap Info Header error\n"); } if (compress != 0) { fprintf(stderr, "圧縮ビットマップには対応していません\n"); exit(1); } if (*BitCount == 4 || *BitCount == 8 || *BitCount == 24 || *BitCount == 32) { ; } else { fprintf(stderr, "%d ビット色には対応していません\n", *BitCount); exit(1); } return count; } /*-------------*/ /* OS/2 bitmap */ /*-------------*/ int rgbtriple(FILE *BMPStream, long used, unsigned char *red, unsigned char *green, unsigned char *blue) { long i; int count = 0; // ビットの並びは B G R for (i = 0; i < used; i++) { blue[i] = fgetc(BMPStream); green[i] = fgetc(BMPStream); red[i] = fgetc(BMPStream); count++; } return count; } /*----------------*/ /* Windows bitmap */ /*----------------*/ int rgbquad(FILE *BMPStream, long used, unsigned char *red, unsigned char *green, unsigned char *blue) { long i; int receive, count = 0; // ビットの並びは B G R 予約 for (i = 0; i < used; i++) { blue[i] = fgetc(BMPStream); green[i] = fgetc(BMPStream); red[i] = fgetc(BMPStream); receive = fgetc(BMPStream); count++; } return count; } void Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],int Count) { int i; fprintf(AStream,"xref\n"); fprintf(AStream,"0 %d\n",Count+1); fprintf(AStream,"0000000000 65535 f \n"); for (i= 0; i<=Count-1;i++) fprintf(AStream,"%0.10d 00000 n \n",ObjectPosArray[i]); } void Write_ContentsObject(FILE *AStream,DWORD ObjectPosArray[],int *ObjectIndex,int w,int h) { int Length; /* PDFコンテンツ */ ObjectPosArray[*ObjectIndex] =(DWORD)ftell(AStream); fprintf(AStream,"%d 0 obj\n",*ObjectIndex+1); fprintf(AStream,"<< /Length %d 0 R >>\n",*ObjectIndex+2); fprintf(AStream,"stream\n"); /* stream */ Length=ftell(AStream); fprintf(AStream,"q\n"); fprintf(AStream,"%d 0 0 %d 0 0 cm\n",w,h); fprintf(AStream,"/Im0 Do\n"); fprintf(AStream,"Q\n"); Length=ftell(AStream)-Length; fprintf(AStream,"endstream\n"); fprintf(AStream,"endobj\n"); *ObjectIndex=*ObjectIndex+1; /* stream Length */ ObjectPosArray[*ObjectIndex] =(DWORD)ftell(AStream); fprintf(AStream,"%d 0 obj\n",*ObjectIndex+1); fprintf(AStream,"%d\n",Length); fprintf(AStream,"endobj\n"); *ObjectIndex=*ObjectIndex+1; } int BMPtoPDF(const char *OpenName,const char *SaveName) { int ObjectIndex; short infosize, bits; long used = 0, color = 0, offset, width, height, xreso, yreso; unsigned char red[256],blue[256],green[256]; DWORD ObjectPosArray[10]; FILE *BMPStream,*AStream; int i,j=0; DWORD BitsSize; // イメージデータのサイズ BYTE *BitsData; // イメージデータ BYTE BitsPalette[768]; // カラーパレット ObjectIndex=0; /* BMPファイルを開く*/ BMPStream=fopen(OpenName,"rb"); if(BMPStream==NULL) { printf("Error : Can not Open File.\n"); return(-1); } // ヘッダ情報 BITMAPFILEHEADER GetBMPSize(BMPStream, &offset); // ヘッダ情報 BITMAPINFOHEADER infoheader(BMPStream, &infosize, &width, &height, &xreso, &yreso, &bits, &color); //color = usedcolor(bits, color); // OS/2 Bitmap if (infosize == 12) { if (bits == 1 || bits == 4 || bits == 8) { used = rgbtriple(BMPStream, color, red, green, blue); } printf("[OS/2 bitmap] --- %d bit %ld color\n", bits, used); } // Windows Bitmap else if (infosize == 40) { if (bits == 1 || bits == 4 || bits == 8) { used = rgbquad(BMPStream, color, red, green, blue); } printf("[Windows bitmap] --- %d bit %ld color\n", bits, used); } else if (infosize == 108) { printf("[other bitmap]\n"); } else { fprintf(stderr, "BITMAP INFOHEADER error\n"); } /* とりあえず、8bitと24bitのみ*/ if (!(bits == 8 || bits == 24)) { printf("Error : 対応していない形式です\n"); fclose(BMPStream); return(-1); } /* PDFファイル作成 */ AStream=fopen(SaveName,"wb+"); if(AStream==NULL) { printf("Error : Can not Create File.\n"); fclose(BMPStream); return(-1); } /* ------------------------------------------------------------- */ /* Writting PDF (PDFの書式) */ /* ------------------------------------------------------------- */ /* PDF のバージョン */ fprintf(AStream,"%%PDF-1.2\n"); /* Catalog */ ObjectPosArray[ObjectIndex] =ftell(AStream); fprintf(AStream,"%d 0 obj\n",ObjectIndex+1); fprintf(AStream,"<<\n"); fprintf(AStream,"/Type /Catalog\n"); fprintf(AStream,"/Pages 2 0 R\n"); /* View Option (100%) */ fprintf(AStream,"/OpenAction [3 0 R /XYZ -32768 -32768 1 ]\n"); fprintf(AStream,">>\n"); fprintf(AStream,"endobj\n"); ObjectIndex++; /* Parent Pages */ ObjectPosArray[ObjectIndex] =ftell(AStream); fprintf(AStream,"%d 0 obj\n",ObjectIndex+1); fprintf(AStream,"<<\n"); fprintf(AStream,"/Type /Pages\n"); fprintf(AStream,"/Kids [ 3 0 R ]\n"); fprintf(AStream,"/Count 1\n"); fprintf(AStream,">>\n"); fprintf(AStream,"endobj\n"); ObjectIndex++; /* Kids Page */ ObjectPosArray[ObjectIndex] =ftell(AStream); fprintf(AStream,"%d 0 obj\n",ObjectIndex+1); fprintf(AStream,"<<\n"); fprintf(AStream,"/Type /Page\n"); fprintf(AStream,"/Parent 2 0 R\n"); fprintf(AStream,"/Resources\n"); fprintf(AStream,"<<\n"); fprintf(AStream,"/XObject << /Im0 4 0 R >>\n"); // ProcSet switch (bits) { case 4 :; case 8 : fprintf(AStream,"/ProcSet [ /PDF /ImageI ]\n");break; default : fprintf(AStream,"/ProcSet [ /PDF /ImageC ]\n");break; } fprintf(AStream,">>\n"); fprintf(AStream,"/MediaBox [ 0 0 %d %d ]\n",width,abs(height)); // コンテンツのオブジェクト番号 switch (bits) { case 4 : ; case 8 : fprintf(AStream,"/Contents 6 0 R\n");break; default : fprintf(AStream,"/Contents 5 0 R\n");break; } fprintf(AStream,">>\n"); fprintf(AStream,"endobj\n"); ObjectIndex++; /* XObject Resource */ ObjectPosArray[ObjectIndex] =ftell(AStream); fprintf(AStream,"%d 0 obj\n",ObjectIndex+1); fprintf(AStream,"<<\n"); fprintf(AStream,"/Type /XObject\n"); fprintf(AStream,"/Subtype /Image\n"); fprintf(AStream,"/Name /Im0\n"); fprintf(AStream,"/Width %d\n",width); fprintf(AStream,"/Height %d\n",abs(height)); fprintf(AStream,"/Filter []\n"); /* BitsPerComponent */ switch (bits) { case 1 : fprintf(AStream,"/BitsPerComponent 1\n");break; case 4 : fprintf(AStream,"/BitsPerComponent 4\n");break; default : fprintf(AStream,"/BitsPerComponent 8\n");break; } /* ColorSpace */ switch (bits) { case 1 : fprintf(AStream,"/ColorSpace /DeviceGray\n");break; case 4 : ; case 8 : fprintf(AStream,"/ColorSpace [/Indexed /DeviceRGB 255 %d 0 R]\n",ObjectIndex+2); break; case 24 : fprintf(AStream,"/ColorSpace /DeviceRGB\n");break; } /* イメージデータのサイズを算出 */ BitsSize =GetBitsSize(width, abs(height),bits); fprintf(AStream,"/Length %d >>\n",BitsSize); /* イメージデータの書き込み */ fprintf(AStream,"stream\n"); /* 生データを突っ込む */ BitsData=(BYTE *)malloc(BitsSize); GetBitsData(BMPStream,offset,BitsData,width,height,bits); TurnBits(BitsData,BitsSize,width,bits); fwrite(BitsData,1,BitsSize,AStream); free(BitsData); fprintf(AStream,"\nendstream\n"); fprintf(AStream,"endobj\n"); ObjectIndex++; // カラーパレットの書き込み if (bits==4 || bits==8) { for (i=0;i<768;i+=3) { BitsPalette[i] = red[j]; BitsPalette[i+1]= green[j]; BitsPalette[i+2]= blue[j]; j++; } ObjectPosArray[ObjectIndex] =ftell(AStream); fprintf(AStream,"%d 0 obj\n",ObjectIndex+1); fprintf(AStream,"<<\n"); fprintf(AStream,"/Length 768\n"); fprintf(AStream,"/Filter []\n"); fprintf(AStream,">>\n"); fprintf(AStream,"stream\n"); fwrite(BitsPalette,1,768,AStream); fprintf(AStream,"\nendstream\n"); fprintf(AStream,"endobj\n"); ObjectIndex++; } /* Contents Stream & Object */ Write_ContentsObject(AStream,ObjectPosArray,&ObjectIndex,width,height); /* CrossReferenceTable */ ObjectPosArray[ObjectIndex] =ftell(AStream); Write_CrossReferenceTable(AStream,ObjectPosArray,(int)ObjectIndex); /* trailer */ fprintf(AStream,"trailer\n"); fprintf(AStream,"<<\n"); fprintf(AStream,"/Size %d\n",ObjectIndex+1); fprintf(AStream,"/Root 1 0 R\n"); fprintf(AStream,">>\n"); fprintf(AStream,"startxref\n"); fprintf(AStream,"%d\n",ObjectPosArray[ObjectIndex]); fprintf(AStream,"%%%%EOF\n"); fclose(BMPStream); fclose(AStream); printf("\nSuccess!\n"); return (0); }
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.