質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

984閲覧

画像ライブラリの作成(PNM)

ryohasegawa

総合スコア437

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2017/07/02 08:02

編集2017/07/03 12:21

画像ライブラリの作成の勉強でPNM形式が一番簡単だという事で調べて見たんですが、データ形式は6種類あって、P1P3はASCIIコードP4P6はバイナリという事が分かりました。


文字のJを表す場合

P1 # This is an example bitmap of the letter "J" 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

最初のP1がデータの種類
#の付いている行がコメント
その次の6 10 は画像の横、縦のサイズ
0と1で0が白、1が黒
という事が分かりました。

また、自分で実際画像を変換(フォトショップで)してみました。
変換済みファイル
これをバイナリエディタで見てみました。

イメージ説明
どうやら、このファイルはP4のデータのようです。
このファイルをP1に変換する方法はないですか?

###追記

cpp

1ifstream fin{ fpath, ios::binary }; 2 3int ch; 4while ((ch = fin.get()) != -1) 5{ 6 if (ch < 10) { 7 cout << hex << uppercase << "0" << ch << ' '; 8 } 9 else { 10 cout << hex << uppercase << ch << ' '; 111213

バイナリモードで開いて、それを16進数で表示しているんですが、この方法だと、Pnが解析できないですよね?

ryo00👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

単に P4 から P1 へ変換するだけならば、ImageMagick を利用する事で実現できます。

convert -compress none p4image.pbm p1image.pbm

投稿2017/07/03 04:51

編集2017/07/03 09:33
kjfkhfhgx

総合スコア48

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2017/07/03 08:03

画像ライブラリの作成の勉強という目的に合致しないかと思われます。またImageMagick(ImageMagicではない)のソースコードの汚さはえげつないものがありますので作成の参考にするのも適当とは思われません。
kjfkhfhgx

2017/07/03 09:36 編集

”P1 形式の画像処理を行う画像ライブラリの作成を行うために” P4形式の画像をP1形式の画像に変換したいのかと想定し回答しましたが、そのような要求ではなかったのですね。
yumetodo

2017/07/03 11:52

ああ、なるほど、そういう解釈も成り立つのか。評価下げてしまったので戻しておきます
guest

0

ベストアンサー

P1にするには1byte=8bitずつ読み込んでBitMaskをつかって1bitずつ取り出して、それが1か0かで文字を書き出すプログラムを書けばいいかと思われます。

追記

とりあえずC++でPBM(P4->P1)の変換を作ってみました
https://github.com/yumetodo/PBMConverter

P1->P4やP2<->P5もすぐできる気がします。

P3<->P6は・・・データ構造で悩み中。

BitMaskを書くのはだるかったのでstd::bitsetを使いました。

追記を見て

バイナリモードで開いて、それを16進数で表示しているんですが、この方法だと、Pnが解析できないですよね?

何故でしょう?まあそのそもなんでstd::istream::get()を呼び出すなんていう面倒な方法でPnのnの解析を試みているのか不思議ですが。

あとなんか不思議なhexdumpの仕方をしますね・・・。std::setfill()とかstd::setw()とか使いましょう?
参考までに私が前に書き捨てたhexdumpするコードを置いておきます
https://gist.github.com/yumetodo/ac2e62583493b1e0ed8f609c686b6c70

投稿2017/07/02 08:28

編集2017/07/03 17:10
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryohasegawa

2017/07/02 08:58

って事は、まずファイルを読み込んで、先頭がP1~P3だったら、それを8bitずつ読み込んでBitMaskをつかって1bitずつ取り出すプログラムを書かないといけないということですか?
ryohasegawa

2017/07/02 09:11

先頭がP1だったら、8bitずつ読み込んでBitMaskをつかって1bitずつ取り出すという事ですね。
yumetodo

2017/07/02 09:13

あああああ、ごめんなさい、P4ですね、bitmaskいるのは。binaryじゃないのにbitmaskとは一体・・・
YAmaGNZ

2017/07/02 09:53

画像サイズ部分やコメントブロックはそのまま読み込まなとダメな点と 横サイズが8の倍数じゃない場合に少し気を付けないいけないですね。
ryohasegawa

2017/07/02 10:08

今までの事をまとめると、ファイルを読み込んで、データ型、コメント、横、縦を読み込んで、データ型でこの先の作業を分ける。 先の作業へ、上のデータ以降(横、縦、改行)のデータを渡して、作業をする感じでいいですか?
yumetodo

2017/07/02 16:09

そうですね。今これに触発されてdecoder/encoder書いてますw
ryohasegawa

2017/07/02 16:35

pnmファイルのですか?
ryohasegawa

2017/07/02 16:38

画像ファイルの読み込みなんですが、今書いているコードは、画像ファイルを16進数で表示しているんですが、16進数にする前にASCIIコードに変換して、P○ってのと。コメント、縦横を取得しないといけないですよね? それとも、16進数をASCIIコードに変換した方がいいですか?
yumetodo

2017/07/02 16:46

>pnmファイルのですか? YES >16進数にする前にASCIIコードに変換して ん?ファイルを文字列として読み込んで上げて、Pnのn部分はC++規格で'0'~'9'の文字コード連続が保証されているから単純に'0'を引けば数値になる。幅と高さはstrtolないしstd::stoi関数で数値変換、あとはひたすらバイナリ列として読み込めばいいのでは
ryohasegawa

2017/07/02 16:52

>ファイルを文字列として読み込んで上げて バイナリでも16進数でもなく、文字列として? 関数かなにかですか? >Pnのn部分はC++規格で'0'~'9'の文字コード連続が保証されている そのようなルールが記載されているサイトなどありますか?
yumetodo

2017/07/02 16:56

>バイナリでも16進数でもなく、文字列として? >関数かなにかですか? そもそもCには文字列はありませんからバイナリですね。 http://yumetodo.hateblo.jp/entry/2017/02/26/151440 >そのようなルールが記載されているサイトなどありますか? http://qiita.com/yumetodo/items/600ca0df422010cbc4c1#comment-20f4865bca2c3c72070d @SaitoAtsushi 氏のコメント及び引用されいてるC/C++規格書を御覧ください。ちなみにUnicodeでも保証がありますからu8/u/U-prefixをつけたリテラルに関しても言えますね。
ryohasegawa

2017/07/02 17:05

>そもそもCには文字列はありませんからバイナリですね。 といいますと、ファイルは全部バイナリ(文字列)で読み込むという事ですね
yumetodo

2017/07/03 00:35

数値として読み込むのも結局内部的には文字列で読み込んでstrtol系関数に投げてますし
ryohasegawa

2017/07/03 12:05

質問の追記描かせて頂きました。
ryohasegawa

2017/07/03 15:54

話がそれてきているので、新しく質問し直す事にしました。
ryohasegawa

2017/07/04 14:49 編集

すいません。自分でも色々整理してみて、勘違いしていた事があったので最後に確認させてください。 .pnmファイルのフォーマット形式はバイナリとASCIIの2種類があり、まずはバイナリかASCIIかを判別する作業が必要なんですよね? その判別を行うには、ファイルを文字列として読み込んであげるんですよね? 回答で「Pnのn部分はC++規格で'0'~'9'の文字コード連続が保証されているから単純に'0'を引けば数値になる」と頂いているんですが、これはもしASCIIの場合だったらという事ですか?バイナリデータだった場合もこうなるんですか? 回答からだいぶ遅くなってしまったんですが、返信いただけると助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問