• ベストアンサー

PING JPEGファイルのExif規格のコメント部を読み込み・書き込みするプログラムソース

以前、表記処理のできるフリーソフトをフリーソフトを教えていただいた者です。 http://oshiete1.goo.ne.jp/qa3911520.html プログラムの中で計算した結果を、画像ファイルのコメント部に書き込むプログラムをC言語で作成しようと思っています。そこで、 int WriteComment(FILE *fd、char *コメント文字列) int ReadComment(FILE *fd、char *コメント文字列) のような関数を内部で使いたいのですが、このような関数ありませんか?あるいは、自作するための参考になるようなお手本となるソースリストありませんか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

 こんにちは。  「libpng」  http://www.libpng.org/  「libexif」  http://libexif.sourceforge.net/  一応参考程度に。  以下PNGからコメントを表示する static void dump(png_textp p) { const char* pszCompress = p->compression == PNG_TEXT_COMPRESSION_zTXt ? "あり" : "なし"; ::printf("[キーワード: %s][コメント: %s][圧縮: %s]\n", p->key, p->text, pszCompress); } int ReadPNG(FILE* pf) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(png_ptr == NULL) { return 0; } png_infop info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 0; } png_init_io(png_ptr, pf); png_set_sig_bytes(png_ptr, 0); png_read_png(png_ptr, info_ptr, 0, NULL); //ココでテキスト部を参照する for(int i = 0; i < info_ptr->num_text; ++i) dump(&info_ptr->text[i]); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 1; } int main() { FILE* pf = fopen("PNGファイル名", "rb"); ReadPNG(pf); fclose(pf); return 0; }  以下JPEGからEXIFを表示する int main() {     ExifData* p = exif_data_new_from_file("JPEGファイル名");     exif_data_dump(p);     exif_data_free(p);     return 0; }

usatan2
質問者

お礼

回答ありがとうございます。 こちらも、なかなか良さそうなページですね。 ご紹介ありがとうございます。 自分で探しても、うまく探せなかったので、本当に助かります。 ダウンロードして、読んでみます。 ところで、Exif規格のコメント部を読み書きするだけでも、libpngを使う場合、zlibが必要なのでしょうか? もしご存知なら、お教えください。

その他の回答 (2)

回答No.3

 こんばんは。御礼頂き感謝いたします。 >>ところで、Exif規格のコメント部を読み書きするだけでも、libpngを使う場合、zlibが必要なのでしょうか?  はい。  libpngの様々な箇所でzlibの関数に依存している為、結局の所zlibをリンクする必要が有ります。  試しにzlibを外してみましたが、至る所でリンクエラーだらけです。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1
usatan2
質問者

お礼

回答ありがとうございます。 なかなか良さそうなページご紹介ありがとうございます。 ダウンロードして、読んでみます。 ありがとうございます。

関連するQ&A

  • PING JPEGファイルのコメント部に書き込みできるフリーソフト

    GIMPのimage - image properties のcomment を使うと、PING JPEGファイルのコメント部に書き込みできるのですが、GIMPを起動させるのが重いので、もっと簡便なコメントだけを読み書きできるフリーソフト探しています。何かありませんか?

  • Cプログラム ファイルの書き込み→読み込み

    #include<stdio.h> void p07a(char *name); void p07b(char *name); //メイン関数 int main() { char name[100]; printf("File Name?"); scanf("%s",name); //ファイルへの書き込み p07a(name); //ファイルからの書き込み p07b(name); puts("!!!!!END!!!!!"); return(0); } //ユーザー関数 void p07a(char *name) { while(1) { int a,b; FILE *fp; fp=fopen("name","w"); scanf("%d,%d",&a,&b); fclose(fp); } } void p07b(char *name) { int i,a[i],b[i],sum,sumb,aave,bave; FILE *fp2; i=0; sum=0; sumb=0; while((fscanf(fp2,"%d,%d",&a[i],&b[i]))!=EOF){ sum+=a[i]; sumb+=b[i]; i++; } aave=sum/i; bave=sumb/i; fclose(fp2); } のプログラムなのですが、書き込むファイル名を入力しても次の処理へ進みません ユーザー関数がおかしいのでしょうか?

  • 2進数から10進数変換

    int henkan(char [ ]) という関数に、”10111”と 2進数で表記されている文字列を数値に変換したいんですが、 どうやったらよいのか教えてください。

  • fgets関数を使用したときの文字あふれについて

    fgets関数を用いて文字列を入力し、その長さを測るプログラムを作っています。 #include <stdio.h> #include <string.h> #define MAX 256 int main ( int, char *[] ); int main ( argc, argv ) int argc; char *argv[]; { char buf[( MAX )]; while ( 1 ){ memset ( buf, 0, sizeof( buf )); fgets ( buf, MAX, stdin ); if( fgets == NULL ){ break; } printf("入力した文字列の長さは%dです\n" ,strlen( buf )); } return 0; } このプログラムでは、256までしか文字列の長さを測ることができません。 もしこのプログラムで256を超える文字列を入力してしまうと、文字のあふれが発生し、 「入力した文字列の長さは256です」 「入力した文字列の長さは(あふれた文字列の長さ)です」 とこのようになってしまいます。 このプログラムで256以上の文字を読み捨てて、 「入力した文字列の長さは(あふれた文字列の長さ)です」 を表示しないようにできるのでしょうか? また読み捨てた文字列の長さを知ることはできるのでしょうか? もしかしたらfgets関数を使用すると不可能なのではないか?と思っています。 分かる方が居ましたらどうか教えて下さい。 よろしくお願いします。

  • c言語 int型の数字をchar型の配列に

    c言語についてです。 int型の数字をchar型の配列に入れたいです。 関数に対してint型の数字を文字列として渡し、 関数内でchar型の配列に格納したいです。 例として、 a(char a[]){  ~~  ~~ } int main(void){ int x = 5678;  ~~  a(x); } とできるようにしたいです。 しかしこれだと5678という値がそのままchar型の一つの配列に入る?ため正しくないです。 欲しい結果としてはちゃんとa関数内で、 a[1] = '5' a[2] = '6' a[3] = '7' a[4] = '8' となってほしいです。 もともと渡す値が”5678”となっていれば結果は正しく出るのですが、 渡す値がint型と決まっているためどうにかして5678を”5678”とすればいいのではないかと考えています。 つまり5678を単純に文字列に変換すればいいのでしょうか? またプログラム内ではsprintfやatolを使用しないで実現させたいです。 難しいかもしれませんがお願いします。 なんだか説明が下手ですみません。 お願いいたします。

  • 配列を返す

    ファイルから読み込んだ一行の文字列を読み込みカンマごとに区切って 返すというプログラムを関数化することで効率を図りたいと思います。 int main() { char buf[1000]; char *str; char *bufG; //ファイルを読み込む  while(fgets(buf,1000,fp) != NULL){//一行ずつ読む str = buf;//先頭アドレスを指す     bufG = //文字列を返す関数  ・  ・  ・ } } //文字列を返す関数 {    for(i = 0; *str != ',' && *str != '\0'; i++){ if(*str == '\n'){ bufG[i] = '\0'; } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; return bufG; } 前の質問で自動変数でこの関数を抜けたら廃棄になるというのは わかったんですが(そういう警告がでました) ここからどのようにすれば求めるプログラムになりますか? 引数とかちょとわからないので関数定義を書きませんでした。 (1)ファイルをよみこむ (2)一行ずつ読み込み文字列をbufにいれる (3)ポインタstrをbufの先頭アドレスにする (4)get_word関数にてポインタをずらしていき カンマがあればそこまでの文字列を返す (5)main関数に戻り変数に代入する (6)終端文字があるまで(4)ー(5)を繰り返す。 (7)さらに行数分繰り返す これらの一連の流れをやりたいのですが わかりません。

  • C言語の穴埋め問題です

    次のプログラムは、初期化により文字列を定義し、辞書式配列にしたとき、どの文字列が先頭にくるかを調べるプログラムなのですが。■■■を教えてください #include <stdio.h> #include <string.h> #define N 5 //関数のプロトタイプ宣言 char *min(char *p[] , int n); int main(void) { char *p[N] = {"Hello" , "Hi" , "Happy" , "HaHaHa" , "Heaven"}; printf("辞書式配列で先頭となる文字列は%s\n" , ■■■); } char *min(char *p[] , int n) { int min; //最小値のアドレス Int i; //カウンタ min = 0; for(i = 1; i < n; i++){ if (strcmp(■■■ , ■■■) > 0){ ■■■= ■■■; } } return ■■■; }

  • C言語でポインタを勉強しています。

    C言語でポインタを勉強しています。 それで、以下のようなプログラムを作成したのですが思ったようにいきません。何が原因でしょうか。 標準入力から全ての文字列を読み取った後、発言者と、「です」を付加した文字列を表示するプログラム 1 # include < stdio . h > 2 # include < string . h > 3 4 5 typedef enum { 6 NAME , // 発言者 7 COMMENT , // 発言 8 MAX _ RECORD _ ARRAY // レコード の 属性 の 数 9 } RecordArrayIndex ; 10 11 12 static const int MAX _ RECORD = 100 ; // 最大 の レコード 数 13 static const int MAX _ STRING = 32 ; // 発言者及 び 発言 の 最大文字数 ( ナル文字 を 含 む ) 14 15 // 関数 プロトタイプ 宣言 16 // record に 発言者 ( name ) と 、 その 発言 ( comment ) を 設定 する 。 17 void setNameAndCommentToRecord ( char * name , char * comment , char * record []) ; 18 // record の 発言 の 語尾 に 「 です 」 を 付 け 加 える 。 19 void appendCommentMeow ( char * record []) ; 20 21 int main ( void ) { 22 char * record [ MAX _ RECORD ][ MAX _ RECORD _ ARRAY ] ; 23 char * name = " 太郎 " ; 24 25 int currentIndex = 0 ; 26 for ( ;; ) { 27 char comment [ MAX _ STRING ] ; 28 if ( gets ( comment ) == NULL ) { 29 break ; 30 } 31 setNameAndCommentToRecord ( name , comment , record [ currentIndex ]) ; 32 appendCommentMeow ( record [ currentIndex ]) ; 33 currentIndex ++ ; 34 } 35 36 int const availableIndex = currentIndex ; 37 for ( int index = 0 ; index < availableIndex ; index ++) { 38 printf ( "% s : 「 % s 」 \ n " , record [ index ][ NAME ] , record [ index ][ COMMENT ]) ; 39 } 40 41 return 0 ; 42 } 43 44 void setNameAndCommentToRecord ( char * name , char * comment , char * record []) { 45 record [ NAME ] = name ; 46 record [ COMMENT ] = comment ; 47 } 48 49 void appendCommentMeow ( char * record []) { 50 strcat ( record [ COMMENT ] , " です " ) ; 51 } 52

  • 大文字を小文字に、小文字を大文字にするプログラム

    問題は、 ファイルにあるアルファベットの大文字を小文字に変換し、小文字は大文字に変換して、ファイルに保存するプログラムを作りなさい というものです。 色々考えて、 #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> int main(int argc,char **argv){ int fd,flag1,flag2; int i,n; char buffer[512],x; fd = open(argv[1],O_RDWR); if(fd == -1) perror("open"); while((n = read(fd,buffer,sizeof(buffer)))>0){ x = buffer[i]; flag1 = islower(x); flag2 = isupper(x); for(i=0;i<n;++i) if(flag1 == 1){ buffer[i] = toupper(buffer[i]); }else if(flag2 == 1){ buffer[i] = tolower(buffer[i]); } write(fd,buffer,n); } close(fd); exit(0); } のようなプログラムを考えましたが、うまくいきません。 toupperのような関数を使ったのは初めてなのでよく使い方が分からずこのようなプログラムになってしまいました。 どうか正しく動くようなプログラムを教えてください。お願いします。

  • 文字列操作

    テキストを読みこんで、そのテキストにある単語を抽出するプログラムを作ろうとしています。単語の区切り文字はスペースかタブで、1文字ずつ読みこんで行こうともいます。 しかし、1文字ずつ読みこむ関数fgetcは返値がint型のようです。1文字ずつよみこみながら読みこんだ文字がスペースかタブで無いか見たいのですが、fgetcのint型返り値をchar文字列と比較するにはどうしたら良いでしょうか。

専門家に質問してみよう