はじめまして!
GIFファイルを読み込んで画像サイズを取得し最終的には反転作業まで行いたいのですがGIFファイルの読み込み方法と画像サイズの取得方法が分かりません。
教えてください!!
> GIFファイルを読み込んで画像サイズを取得し最終的には反転作業まで行いたいのですがGIFファイルの読み込み方法と画像サイズの取得方法が分かりません。
とりあえず,こんなページがあります。
http://www.geocities.co.jp/SiliconValley/3453/gif_info/index_jp.html
画像サイズは簡単に読み込めますが,イメージデータの読み込みは,
LZWのデコードが絡むので面倒です。
#特許もあるし。
OleLoadPicture使って読み込んで,IPicture::Renderして,
それを反転させる方のが一番簡単だと思います。
ありがとうございます。
>OleLoadPicture使って読み込んで,IPicture::Renderして,
それを反転させる方のが一番簡単だと思います。
のやり方が分かりません。
サンプル的に教えていただけませんか?
>画像サイズは簡単に読み込めますが,
画像サイズはどのように取り込んだら良いのでしょうか?何度も試しましたが
出来ませんでした。
>OleLoadPicture使って読み込んで,IPicture::Renderして,
>それを反転させる方のが一番簡単だと思います。
例を挙げて教えてくださいませんか??
> 画像サイズはどのように取り込んだら良いのでしょうか?何度も試しましたが
> 出来ませんでした。
どのようなコードを書きましたか?
抜粋してみてください。
> >OleLoadPicture使って読み込んで,IPicture::Renderして,
> >それを反転させる方のが一番簡単だと思います。
> 例を挙げて教えてくださいませんか??
何がわからないのですか?
OleLoadPictureやIPicture::Renderを使った描画は検索エンジンで検索すれば見つかると思いますが。
純粋にC言語だけで(fread等で)GIFの画像サイズと縦・横のサイズの取得はできないのでしょうか?
編集 削除> 純粋にC言語だけで(fread等で)GIFの画像サイズと縦・横のサイズの取得はできないのでしょうか?
可能ですよ。
私が2003/07/24(木) 14:35:20に書いたURLにある,GIFの仕様書(の邦訳)などを参考にすれば,
問題なく取得できると思いますが。
GIF Headerから画像全体の横と縦のサイズは取得できたのですが、imageblockのイメージサイズと縦と横のサイズが取得できません。それと、Global Color Tabelの取得の仕方がどうしても出来ませんでした。
編集 削除GIF Headerから画像全体の横と縦のサイズは取得できたのですが、imageblockのイメージサイズと縦と横のサイズが取得できません。それと、Global Color Tabelの取得の仕方がどうしても出来ませんでしたのでご教授願います。
編集 削除> imageblockのイメージサイズと縦と横のサイズが取得できません。
GIFを解析している部分のコードを載せてみてはどうでしょう。
そうすれば回答を得やすいかと。
> Global Color Tabelの取得の仕方がどうしても出来ませんでしたのでご教授願います
仕様書にも書いてある通り、Global Color Tabel を持っていないGIFも存在します。
ですので、まずテストに使用したGIFが Global Color Tabel を持っているかを確認してみては。
いくら正しいコードを書いていても、存在しない Global Color Tabel は取得できませんから。
//GIFHeader部分
int GetGIFSize(int GIFStream, int *gsize,
int *width, int *height, int *Ncolos)
{
unsigned char count;
unsigned char bitdata, bcindex,ratio;
//int var_long;
unsigned short var_short;
unsigned char s,s1;
char color[765];
//GIFファイルサイズ
struct stat buf;
fstat(GIFStream,&buf);
*gsize = buf.st_size;
// GIF 認識文字 "GIF" (0x47 0x49 0x46の固定値)
if (_read(GIFStream,&s,3) == 3) {
if (memcmp(&s, "GIF", 3) == 0) {
printf("[GIF] GIF file\n");
}
else {
// fprintf(stderr, "%s : Not a GIF file\n", s);
exit(1);
}
count += 3;
}
//ヴァージョンの確認
//("87a"の場合は,0x38 0x37 0x61の固定値 "89a"の場合は,0x38 0x39 0x61の固定値となる。)
if (_read(GIFStream,&s1,3) == 3) {
if (memcmp(&s1, "87a", 3)== 0) {
printf("Version GIF file\n");
}
else if (memcmp(&s1, "89a", 3)== 0) {
printf("Version GIF file\n");
}
else {
//fprintf(stderr, "%s : Not a Version GIF file\n", s1);
exit(1);
}
count += 3;
}
// GIF画像全体の幅 (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Width : %ld [pixel]\n", var_short);
*width = var_short;
count += 2;
}
// GIF画像全体の高さ (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Height : %ld [pixel]\n", var_short);
*height = var_short;
count += 2;
}
//color map がありますか??
unsigned char b = count++;
*Ncolos = 1 << ((b & 7) + 1);
if ((b &0x80) == 0)
{ printf("No color map\n");
*ncolors = 0;
}
//backgroud color
++count;
//bitdata読み込み
if (_read(GIFStream,&bitdata, 1) == 1) {
unsigned bit = bitdata & 0x07;
unsigned bbit = 1 << bit + 1;
unsigned bbbit = bitdata >> 3;
count +=1;
}
//背景色index
if (_read(GIFStream,&bcindex, 1) == 1) {
unsigned char bc = bcindex;
printf(" \n");
count += 1;
}
//ピクセルの縦横比
if (_read(GIFStream,&ratio, 1) == 1) {
unsigned char rt = ratio;
printf(" \n");
//*pixcel = (var_short + 15)/64; が実際の比率
count += 1;
}
return count;
}
//Global Color Table Flag が存在する場合のTableの情報
/* int GIFColorTable(int GIFStream,
int used,
unsigned char *red,
unsigned char *green,
unsigned char *blue)
{
int size,i;
unsigned char colortable[256][3];
struct channnel{
Red = 0;
Blue = 1;
Green = 2;
}
for(i = 0;i<size;i++){
_read(GIFStream,&colortable[i],3);
}
int receive,count;
// ビットの並びは B G R 予約??????
for (i = 0; i < used; i++) {
blue[i] = _read(GIFStream,&blue,1);
green[i] = _read(GIFStream,&green,1);
red[i] = _read(GIFStream,&red,1);
receive = _read(GIFStream,&receive,1);
count++;
}
return count;
}*/
/*------------------------------------------------------------------*/
/* Image Block */
/*------------------------------------------------------------------*/
int ImageBlock(int GIFStream,int *leftposition, int *topposition,
int *imagew, int *imageh, int *bsize)
{
int count = 0;
int var_long;
unsigned short var_short;
unsigned char s2;
// Image Separator (1byte)
if (_read(GIFStream,&s2, 1) == 1) {
if (memcmp(&s2, "2c", 1)== 0) {
printf("Image block\n");
}
else {
exit(1);
}
count += 1;
}
//Image Left Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_long, 2) == 2) {
*leftposition = var_long;
count += 2;
}
// Image TOP Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_long, 2) == 2) {
*topposition = var_long;
count += 2;
}
// ImageBlockの幅
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Width : %d [pixel]\n", var_short);
*imagew = var_short;
count += 2;
}
// ImageBlockの高さ
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Height : %d [pixel]\n", var_short);
*imageh = var_short;
count += 2;
}
//Local Color Table Flag, Interlace Flag
//Sort Flag, Reserved, Size of Local Color Table
if (_read(GIFStream,&var_long, 1) == 1) {
count += 1;
}
//Local Color Table (Global Color Table Flagが1の場合に存在する。)
//LZW Mimimum Code Side(LZWコードの最小ビット数)
if (_read(GIFStream,&var_long, 1) == 1) {
count += 1;
}
//Block Size(イメージサイズ)
if (_read(GIFStream,&var_long, 1) == 1) {
printf(" Block Size : %d [bit]\n", var_long);
*bsize = var_long;
count += 1;
}
else {
fprintf(stderr, "GIF Image Block error\n");
}
return count;
}
こんな感じでイメージサイズと高さ・幅を抽出できればと思ったのですがどうですか??
気づいた部分を修正してみました。
仕様書を見ながらソースを追えば解かってくるかと。
ただ動作確認していないので正しい保証はありません。参考程度に。
-----------------------------------------------
int GetGIFSize(
int GIFStream,
int *gsize,
int *width,
int *height,
int *Ncolos
) {
:省略
// //color map がありますか??
// unsigned char b = count++;
// *Ncolos = 1 << ((b & 7) + 1);
// if ((b &0x80) == 0) {
// printf("No color map\n");
// *ncolors = 0;
// }
//
// //backgroud color
// ++count;
//bitdata読み込み
if (_read(GIFStream,&bitdata, 1) == 1) {
// unsigned bit = bitdata & 0x07;
// unsigned bbit = 1 << bit + 1;
//
// unsigned bbbit = bitdata >> 3;
count +=1;
// bitdataの最上位ビットをチェックしてGlobal Color Tableが存在するなら
// 色数を得る。存在しない場合は 0 を設定
*Ncolos = ((bitdata & 0x80) ? (2 << (bitdata & 0x07)) : 0);
}
:省略
}
//Global Color Table Flag が存在する場合のTableの情報
int GIFColorTable(
int GIFStream,
int used,
unsigned char *red,
unsigned char *green,
unsigned char *blue
) {
// ビットの並びはRGB
// red,green,blueはメモリ確保済みとして
for (int i = 0; i < used; i++) {
_read(GIFStream, &red[i], 1);
_read(GIFStream, &green[i], 1);
_read(GIFStream, &blue[i], 1);
}
return used * 3 // Tableのサイズ(Byte)を返しておく?
}
/*------------------------------------------------------------------*/
/* Image Block */
/*------------------------------------------------------------------*/
int ImageBlock(
int GIFStream,
int *leftposition,
int *topposition,
int *imagew,
int *imageh,
int *bsize
) {
:省略
// // Image Separator (1byte)
// if (_read(GIFStream,&s2, 1) == 1) {
// if (memcmp(&s2, "2c", 1)== 0) {
// printf("Image block\n");
// }
// else {
// exit(1);
// }
// count += 1;
// }
:省略
// //Block Size(イメージサイズ)
// if (_read(GIFStream,&var_long, 1) == 1) {
// printf(" Block Size : %d [bit]\n", var_long);
// *bsize = var_long;
// count += 1;
// }
// else {
// fprintf(stderr, "GIF Image Block error\n");
// }
//Block Size(イメージサイズ)
*bsize = 0;
while (_read(GIFStream,&var_long, 1) == 1) {
if (var_long == 0) break;
*bsize += (1 + var_long); // データ副ブロックのブロック寸法領域のサイズを足す
_lseek(GIFStream, var_long, SEEK_CUR); // 次のデータ副ブロック開始位置へ
}
return count + *bsize;
}
/*------------------------------------------------------------------*/
/* main
/*------------------------------------------------------------------*/
int main() {
int GIFStream = _open("xxxx.gif", ...);
// Logical Screen Descriptor 情報取得
int gsize, width, height, Ncolos;
GetGIFSize(GIFStream, &gsize, &width, &height, &Ncolos);
// Global Color Table 情報取得
if (Ncolos > 0) GIFColorTable(GIFStream, Ncolos, ...);
// ブロックを解析
int var_long, iImageNum = 0;
while (_read(GIFStream, &var_long, 1) == 1) {
switch (var_long) {
case 0x2C: // イメージ記述ブロック
ImageBlock(GIFStream, ...);
iImageNum++;
break;
case 0x3B: // ストリーム終了
goto End;
case 0x21: // 拡張ブロック
_lseek(GIFStream, 1, SEEK_CUR); // ラベル領域分を飛ばす
default:
while (_read(GIFStream, &var_long, 1) == 1) {
if (var_long == 0) break;
_lseek(GIFStream, var_long, SEEK_CUR); // 次のデータ副ブロック開始位置へ
}
break;
}
}
:End
// 後処理
printf("%d 枚の画像が格納されています\n", iImageNum);
return 0;
}
やって見たのですが、どうしてもGlobal Color Table でエラーが出てしまい回避出来ません。ご教授お願いします。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
//GIFHeader部分
int GetGIFSize(int GIFStream, int *gsize,
int *width, int *height, int *Ncolos)
{
unsigned char count;
unsigned char bitdata, bcindex,ratio;
//int var_long;
unsigned short var_short;
unsigned char s,s1;
char color[765];
//GIFファイルサイズ
/* struct stat buf;
fstat(GIFStream,&buf);
*gsize = buf.st_size;*/
// GIF 認識文字 "GIF" (0x47 0x49 0x46の固定値)
if (_read(GIFStream,&s,3) == 3) {
if (memcmp(&s, "GIF", 3) == 0) {
printf("[GIF] GIF file\n");
}
else {
// fprintf(stderr, "%s : Not a GIF file\n", s);
exit(1);
}
count += 3;
}
//ヴァージョンの確認
//("87a"の場合は,0x38 0x37 0x61の固定値 "89a"の場合は,0x38 0x39 0x61の固定値となる。)
if (_read(GIFStream,&s1,3) == 3) {
if (memcmp(&s1, "87a", 3)== 0) {
printf("Version GIF file\n");
}
else if (memcmp(&s1, "89a", 3)== 0) {
printf("Version GIF file\n");
}
else {
//fprintf(stderr, "%s : Not a Version GIF file\n", s1);
exit(1);
}
count += 3;
}
// GIF画像全体の幅 (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Width : %ld [pixel]\n", var_short);
*width = var_short;
count += 2;
}
// GIF画像全体の高さ (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Height : %ld [pixel]\n", var_short);
*height = var_short;
count += 2;
}
//color map がありますか??
/* unsigned char b = count++;
*Ncolos = 1 << ((b & 7) + 1);
if ((b &0x80) == 0)
{ printf("No color map\n");
*ncolors = 0;
}*/
//backgroud color
//++count;
//bitdata読み込み
if (_read(GIFStream,&bitdata, 1) == 1)
{
// unsigned bit = bitdata & 0x07;
// unsigned bbit = 1 << bit + 1;
// unsigned bbbit = bitdata >> 3;
count +=1;
//bitdataの最上位ビットをチェックしてGlobal Color Table が存在するなら
//色数を得る。存在しない場合は、0を設定。
*Ncolos = ((bitdata & 0x80) ? (2 << (bitdata & 0x07)): 0);
}
//背景色index
if (_read(GIFStream,&bcindex, 1) == 1) {
unsigned char bc = bcindex;
printf(" \n");
count += 1;
}
//ピクセルの縦横比
if (_read(GIFStream,&ratio, 1) == 1) {
unsigned char rt = ratio;
printf(" \n");
//*pixcel = (var_short + 15)/64; が実際の比率
count += 1;
}
return count;
}
//Global Color Table Flag が存在する場合のTableの情報
int GIFColorTable(int GIFStream,
long used,
unsigned char *red,
unsigned char *green,
unsigned char *blue)
{
//ビットの並びはRGB
//red,blue,greenはメモリ確保済みとして、
for(int i = 0; i < used; i++)
{
_read(GIFStream, &red[i], 1);
_read(GIFStream, &green[i], 1);
_read(GIFStream, &blue[i], 1);
}
return used*3;
}
/*------------------------------------------------------------------*/
/* Image Block */
/*------------------------------------------------------------------*/
int ImageBlock(int GIFStream,int *leftposition, int *topposition,
int *imagew, int *imageh, int *bsize)
{
int count = 0;
int var_long;
unsigned short var_short;
unsigned char s2;
// Image Separator (1byte)
/* if (_read(GIFStream,&s2, 1) == 1) {
if (memcmp(&s2, "2c", 1)== 0) {
printf("Image block\n");
}
else {
exit(1);
}
count += 1;
}*/
//Image Left Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_long, 2) == 2) {
*leftposition = var_long;
count += 2;
}
// Image TOP Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_long, 2) == 2) {
*topposition = var_long;
count += 2;
}
// ImageBlockの幅
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" ImWidth : %d [pixel]\n", var_short);
*imagew = var_short;
count += 2;
}
// ImageBlockの高さ
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" ImHeight : %d [pixel]\n", var_short);
*imageh = var_short;
count += 2;
}
//Local Color Table Flag, Interlace Flag
//Sort Flag, Reserved, Size of Local Color Table
if (_read(GIFStream,&var_long, 1) == 1) {
count += 1;
}
//Local Color Table (Global Color Table Flagが1の場合に存在する。)
//LZW Mimimum Code Side(LZWコードの最小ビット数)
if (_read(GIFStream,&var_long, 1) == 1) {
count += 1;
}
//Block Size(イメージサイズ)
/* if (_read(GIFStream,&var_long, 1) == 1) {
printf(" Block Size : %d [bit]\n", var_long);
*bsize = var_long;
count += 1;
}
else {
fprintf(stderr, "GIF Image Block error\n");
}*/
//Block Size(イメージサイズ)
*bsize = 0;
while (_read(GIFStream, &var_long, 1) == 1)
{
if(var_long == 0) break;
//データ副ブロックのブロック寸法領域のサイズを足す。
*bsize += (1 + var_long);
//次のデータ副ブロック開始位置へ
_lseek(GIFStream, var_long,SEEK_CUR);
}
return count + *bsize;
}
//main
int main()
{
int GIFStream = _open("F:\\開発\\GIF関連\\GIF画像\\m1.gif", _O_RDONLY|_O_BINARY);
//Logical Screen Descripter 情報取得
int gsize, width, height, Ncolos;
GetGIFSize(GIFStream, &gsize, &width, &height, &Ncolos);
//Global Color Table情報取得
int used ;
unsigned char red,blue, green;
if (Ncolos > 0) GIFColorTable(GIFStream, used, &red, &green, &blue);
//ブロックを解析
int var_long, iImageNum = 0;
int leftposition, topposition, imagew, imageh, bsize;
while (_read(GIFStream, &var_long, 1) == 1)
{
switch (var_long){
case 0x2C : //イメージ記述ブロック
ImageBlock(GIFStream,&leftposition, &topposition, &imagew, &imageh, &bsize);
iImageNum++;
break;
case 0x3B ://ストリーム終了
goto End;
case 0x21 : //拡張ブロック
//ラベル領域を飛ばす!!
_lseek(GIFStream, 1, SEEK_CUR);
default :
while (_read(GIFStream, &var_long, 1) == 1){
if (var_long == 0) break;
//次のデータ副ブロックへ
_lseek(GIFStream, var_long, SEEK_CUR);
}
break;
}
}
End:
//後処理
printf("%d枚の画像が格納されています。\n",iImageNum);
return 0;
}
> //Global Color Table情報取得
> int used ;
> unsigned char red,blue, green;
> if (Ncolos > 0) GIFColorTable(GIFStream, used, &red, &green, &blue);
配列、又は malloc() 等を使用して必要なサイズ分のメモリを確保しないと…
> int var_long, iImageNum = 0;
> int leftposition, topposition, imagew, imageh, bsize;
> while (_read(GIFStream, &var_long, 1) == 1)
var_long = 0xFFFFFFFF;
_read(GIFStream, &var_long, 1)
と4バイトの変数に_read()で1バイトデータを読込む、なんてすると
var_longの中身は 0xFFFFFF** と上位3バイトには以前の値が残り正確な値が取得できません。
(まあ、2つ目は私の書いたコードなんで私の間違いですが…)
こんなのが重なってエラーが出ているのでしょう。
とりあえずソース貼らせて貰います。VC6.0 + SP5 Win98 で動作確認済み。
後は仕様書を見ながらで何とかなるでしょう。
-----------------------------------------------
//GIFHeader部分
int GetGIFSize(int GIFStream, int *gsize, int *width,
int *height, int *Ncolos)
{
unsigned char count = 0;
unsigned char bitdata, bcindex,ratio;
unsigned short var_short;
unsigned char s[4], s1[4];
// GIF 認識文字 "GIF" (0x47 0x49 0x46の固定値)
if (_read(GIFStream,&s,3) == 3) {
if (memcmp(&s, "GIF", 3) == 0) printf("[GIF] GIF file\n");
else exit(1);
count += 3;
}
//ヴァージョンの確認
//("87a"の場合は,0x38 0x37 0x61の固定値 "89a"の場合は,0x38 0x39 0x61の固定値となる。)
if (_read(GIFStream,&s1,3) == 3) {
if (memcmp(&s1, "87a", 3)== 0) printf("Version GIF file\n");
else if (memcmp(&s1, "89a", 3)== 0) printf("Version GIF file\n");
else exit(1);
count += 3;
}
// GIF画像全体の幅 (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Width : %ld [pixel]\n", var_short);
*width = var_short;
count += 2;
}
// GIF画像全体の高さ (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" Height : %ld [pixel]\n", var_short);
*height = var_short;
count += 2;
}
//bitdata読み込み
if (_read(GIFStream,&bitdata, 1) == 1) {
count +=1;
//bitdataの最上位ビットをチェックしてGlobal Color Table が存在するなら
//色数を得る。存在しない場合は、0を設定。
*Ncolos = ((bitdata & 0x80) ? (2 << (bitdata & 0x07)): 0);
}
//背景色index
if (_read(GIFStream,&bcindex, 1) == 1) {
unsigned char bc = bcindex;
printf(" \n");
count += 1;
}
//ピクセルの縦横比
if (_read(GIFStream,&ratio, 1) == 1) {
unsigned char rt = ratio;
printf(" \n");
count += 1;
}
return count;
}
//Global Color Table Flag が存在する場合のTableの情報
int GIFColorTable(int GIFStream,
long used,
unsigned char *red,
unsigned char *green,
unsigned char *blue)
{
//ビットの並びはRGB
//red,blue,greenはメモリ確保済みとして、
for(int i = 0; i < used; i++) {
_read(GIFStream, &red[i], 1);
_read(GIFStream, &green[i], 1);
_read(GIFStream, &blue[i], 1);
}
return used*3;
}
/*------------------------------------------------------------------*/
/* Image Block */
/*------------------------------------------------------------------*/
int ImageBlock(int GIFStream,int *leftposition, int *topposition,
int *imagew, int *imageh, int *bsize)
{
int count = 0;
unsigned short var_short;
//Image Left Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
*leftposition = var_short;
count += 2;
}
// Image TOP Position (0x1234の場合は,0x34 0x12と格納される。)
if (_read(GIFStream,&var_short, 2) == 2) {
*topposition = var_short;
count += 2;
}
// ImageBlockの幅
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" ImWidth : %d [pixel]\n", var_short);
*imagew = var_short;
count += 2;
}
// ImageBlockの高さ
if (_read(GIFStream,&var_short, 2) == 2) {
printf(" ImHeight : %d [pixel]\n", var_short);
*imageh = var_short;
count += 2;
}
//Local Color Table Flag, Interlace Flag
//Sort Flag, Reserved, Size of Local Color Table
unsigned char var_byte;
if (_read(GIFStream,&var_byte, 1) == 1) count += 1;
if ((var_byte & 0x80)) {
//Local Color Tableが存在したが面倒なので無視する
_lseek(GIFStream, (2 << (var_byte & 0x07)), SEEK_CUR);
count += (2 << (var_byte & 0x07));
}
//LZW Mimimum Code Side(LZWコードの最小ビット数)
if (_read(GIFStream,&var_byte, 1) == 1) {
count += 1;
}
//Block Size(イメージサイズ)
*bsize = 0;
while (_read(GIFStream, &var_byte, 1) == 1) {
if(var_byte == 0) break;
//データ副ブロックのブロック寸法領域のサイズを足す。
*bsize += (1 + var_byte);
//次のデータ副ブロック開始位置へ
_lseek(GIFStream, var_byte, SEEK_CUR);
}
return count + *bsize;
}
int main() {
int GIFStream = _open("F:\\siisiselogo.gif", _O_RDONLY|_O_BINARY);
//Logical Screen Descripter 情報取得
int gsize, width, height, Ncolos;
GetGIFSize(GIFStream, &gsize, &width, &height, &Ncolos);
//Global Color Table情報取得
unsigned char *red, *blue, *green;
red = blue = green = NULL;
if (Ncolos > 0) {
red = (unsigned char*)malloc(Ncolos);
blue = (unsigned char*)malloc(Ncolos);
green = (unsigned char*)malloc(Ncolos);
GIFColorTable(GIFStream, Ncolos, red, green, blue);
}
//ブロックを解析
unsigned char var_byte;
int iImageNum = 0;
int leftposition, topposition, imagew, imageh, bsize;
while (_read(GIFStream, &var_byte, 1) == 1)
{
switch (var_byte){
case 0x2C : //イメージ記述ブロック
ImageBlock(GIFStream,&leftposition, &topposition, &imagew, &imageh, &bsize);
iImageNum++;
break;
case 0x3B ://ストリーム終了
goto End;
case 0x21 : //拡張ブロック
//ラベル領域を飛ばす!!
_lseek(GIFStream, 1, SEEK_CUR);
default :
while (_read(GIFStream, &var_byte, 1) == 1){
if (var_byte == 0) break;
//次のデータ副ブロックへ
_lseek(GIFStream, var_byte, SEEK_CUR);
}
break;
}
}
End:
//後処理
if (red != NULL) free(red);
if (green != NULL) free(green);
if (blue != NULL) free(blue);
_close(GIFStream);
printf("%d枚の画像が格納されています。\n",iImageNum);
return 0;
}
ありがとうございます!!ここから以前Junixさんの掲示板を拝見しまして、
GifのPDF化に帰着したいのですが、イメージの高さ・幅・サイズのみでPDFにする事が出来るでしょうか??(JPEGは出来ていた、bmpはカラーパレットのオブジェクトを使用していたし、生のデータをstream間に挿入しなければならない。ということは、gifは・・・PDFのLZWDecodeのみで行けるのかな?)
GIF画像のヘッダ部分を除いたイメージデータのみをメモ帳に表示することはできますか?
編集 削除できません。バイナリエディタを使って観察してください。
編集 削除ご返答ありがとうございます。
ということは、stream間にイメージデータを挿入することはできないのでしょうか?自分の考えですが、LZWアルゴリズムのイメージデータ部分のみstream間に挿入すれば良いと考えたのですが、この考え方は間違っているのでしょうか??
私ができないと言ったのは「イメージデータをメモ帳で見ることはできない」ということです。
その他のことは、テスト&解析してみないと分かりません。ただ、「iText」(java)という著名な
ライブラリでも無圧縮GIFファイルは扱えてもLZWのGIFファイルは扱えませんから、LZWデータを
そのままstream間に突っ込むということはできないような気がします。
ありがとうございます。ということは、LZWのGIFファイルはPDF化にできないということですね。無圧縮なGIFファイルならPDF化は可能ですか??
編集 削除この辺りのことは実際にテスト&解析してみないと分かりません。
また、「iText」の例ではLZWライセンスを回避しながらGIF2PDFは
できないという事を例として出してみました。言葉足らずですみません。
前回の件を要約しますと、
< GIF2PDF(無圧縮) >
LZWライセンスを回避して作成することができます。
< GIF2PDF(LZW) >
LZWライセンスを回避できない可能性が非常に高い。
(圧縮されたデータを展開する必要があるかもしれない)
ということです。
おそらくこの辺りの情報はネット上などには流れていないと
思いますが、PDFファイルを解析しまくれば何とかなりますので、
がんばってください。
# GIF2PDF(無圧縮)については「iText」で吐き出されたファイルを解析すれば楽勝だと思います。
ありがとうございます。大変勉強になりました。GIF2PDF(無圧縮)についての「iText」で吐き出されたファイルというのはどこにおいてあるのでしょうか?
また、言語はjavaな様ですが、C言語ではないでしょうか?何分C言語しか勉強していないので・・・
> ...「iText」で吐き出されたファイルというのはどこにおいてあるのでしょうか?
「iText」ライブラリ [en]
http://www.lowagie.com/iText/
「iTextFront」iTextを使っただけのソフトウェア [ja]
http://www.vector.co.jp/soft/win95/writing/se258136.html
ファイルは「iTextFront」を使ってGIF(無圧縮)からPDFファイルに変換して下さい。
あとはメモ帳(秀丸)とバイナリエディタを使って観察すればフォーマットがわかるかと思います。
<PDF作成ライブラリのリンク集(おまけ)>
PDFLib (C言語など多種多様) [en]
http://www.pdflib.com/
CLibPDF (C言語など多種多様) [en]
http://www.fastio.com/
Hobbit's PDF Library (java) [ja]
http://www.puzzle.gr.jp/programming/pdf/doc/index.html.ja
PDFJ (Perl) [ja]
http://hp1.jonex.ne.jp/~nakajima.yasushi/PDFJ.jp.html
ReportLab (Python?) [en] <- 作成されるファイルが壊れている場合がある
http://www.reportlab.com/
iText (java) [en]
http://www.lowagie.com/iText/
Ghostscript (C言語) [en] <- 厳密に言うとライブラリではない
http://www.cs.wisc.edu/~ghost/
PowerPdf (Delphi) [en]
http://www.est.hi-ho.ne.jp/takeshi_kanno/powerpdf/
ほとんどがGNU系のライブラリと有料ライブラリです。
一般のフリーソフトはありません。非常に残念です。
ありがとうございます。無圧縮のGIF画像はネットに転がっているのでしょうか??
編集 削除Googleなどを使って検索してみてください。見つかるはずです。
http://www.google.co.jp/
無圧縮のGIF画像を必死で探してみたんですけどありませんでした。どこかにおいてありそうなサイトってありますか?
編集 削除こんな感じで探してください。
http://www.google.co.jp/search?hl=ja&ie=UTF-8&oe=UTF-8&q=GIF+%E7%84%A1%E5%9C%A7%E7%B8%AE+&lr=
UcGIF [bmp2gif]
http://www.h2.dion.ne.jp/~wogota/pub/pub2-00.htm
など、、、。
お久しぶりです。色々調査しましたが、
LZWライセンスを使用した場合PDFにするには
どうすれば良いでしょうか??
たとえば pbmplus さんが一番上で紹介している PDFLib は
ドキュメントを読む限り GIF の読み込みに対応していると
あるので、多分LZW圧縮されたGIFファイルを読み込んで PDF
に変換することもできると思います。
ちゃんと調べましたか?
LZW を使わない GIF のデコードもあるみたいよ。
こちらからどうぞ。
http://homepage1.nifty.com/uchi/