teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

tuiki

2018/02/19 08:16

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -51,4 +51,56 @@
51
51
  これらを修正すれば、正しい画像が出力されると思います。
52
52
  ※私の環境でデータ部のロジックを修正し、出力された画像ファイルをバイナリエディタで正しいファイルサイズ・データサイズに書き換えてみたところ、正常な画像となりました。
53
53
 
54
- 頑張ってみてください。
54
+ 頑張ってみてください。
55
+
56
+ コメントを受けて説明追記
57
+ ---
58
+ 今回、純粋に画像にしたいデータの1行分の長さは、7列 x 2倍 x 3バイト = 42バイトです。
59
+
60
+ 式にすると
61
+ `画像の実データ長(①)` = `x * zoom * 3`
62
+ です。
63
+
64
+ これを画像ファイルにする際は1行を4の倍数に揃えたいので、4で割った余りの数を4から引いた数だけNULLを補完します。
65
+ 必要なNULLの数は、42バイト を 4バイト で割った余り、2バイトを 4バイトから引いた値、2バイトです。
66
+
67
+ 式にすると
68
+ `NULLデータ長(z)` = `4 - ((x * zoom * 3) mod 4)`
69
+ です。
70
+
71
+ ※ここ、わかりにくいですかね。
72
+ ※例えば倍率が1の場合、 7 * 1 * 3 = 21バイトで、4で割った余りは1です。4の倍数にするためには4-1=3バイトのNULLが必要ということです。
73
+
74
+
75
+ 画像データにする時の1行の長さは、`画像の実データ長(①)` + `NULLデータ長(z)`ですので、今回は 42バイト + 2バイト = 44バイトです。
76
+ 式にすると
77
+ `1行のデータ長(②)` = `(x * zoom * 3) + (4 - ((x * zoom * 3) mod 4))`
78
+ です。
79
+
80
+ ---
81
+ 画像データ部のサイズは、`1行のデータ長(②)` * `行数` ですので、今回は 44バイト x 7行 x 2倍 = 616バイトです。
82
+ 式にすると
83
+ `画像データサイズ(③)` = `((x * zoom * 3) + (4 - ((x * zoom * 3) mod 4))) * y * zoom`
84
+ です。
85
+
86
+ ---
87
+ 最後に全体のファイルサイズは、`ヘッダ部のサイズ(54バイト)` + `画像データサイズ(③)`ですので、今回は 54 + 616バイト = 670バイトです。
88
+ 式にすると
89
+ 全体のファイルサイズ(f) = `54 + (((x * zoom * 3) + (4 - ((x * zoom * 3) mod 4))) * y * zoom)`
90
+ となります。
91
+
92
+ ---
93
+ ご覧のとおり、Nullデータ長(z)は列数(x)と倍率(zoom)に依存するため固定値とはならず、最終的な計算式にも出現しません。
94
+
95
+ zの代わりに倍率zoomを要素とするなら、
96
+ `f(x, y, zoom) = 54 + (((x * zoom * 3) + (4 - ((x * zoom * 3) mod 4))) * y * zoom)`
97
+ という回答になります。
98
+
99
+ zoomを2倍と固定してf(x,y)で式にするなら
100
+ `f(x, y) = 54 + (((x * 6) + (4 - ((x * 6) mod 4))) * y * 2)`
101
+ です。
102
+
103
+ 合計の式というよりは過程で求めた1行のバイト数やNULLバイト数が正しく算出できるか、というところが重要ですね。
104
+ 上記も1行ですっきり書いてしまうよりは、過程の計算をそれぞれ変数に代入していった方が、結果がおかしいときに原因を探りやすくなると思います。
105
+
106
+ 参考になれば幸いです。

2

syuusei 2

2018/02/19 08:15

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -13,15 +13,19 @@
13
13
  正:9E 02 00 00
14
14
  誤:CA 00 00 00
15
15
 
16
- これもリトルエンディアンで書かれていますので、正解は`0x029E`です。
16
+ これもリトルエンディアンで書かれていますので、正解の方は`0x029E`、10進数は670という数字になっています。
17
- 10進数では670という数字になります。
17
+ この値の根拠を考えてみます。
18
18
 
19
- この根拠を考えてみます。
20
- ヘッダ部は54バイト)なので、データ部は616バイトということになります。
19
+ ヘッダ部は54バイトなので、データ部は616バイトということになります。
21
20
 
22
- 14行x14列をカラーコード3バイトで表すので、単純計算では14行 * 14列 * 3バイト = 588バイトです。
21
+ 14行x14列をカラーコード3バイトで表すので、単純計算では
23
- しかし1行ごとに4の倍数のバイト数となるように00が補われますので、14行 * ((14列 * 3バイト) `+ 2バイト`) = 616バイトとなるわけです。
22
+ 14行 * 14列 * 3バイト = 588バイト
23
+ です。
24
24
 
25
+ しかし1行ごとに4の倍数のバイト数となるようにNULL(00)を補う必要があるので、
26
+ 14行 * ((14列 * 3バイト) `+ 2バイト`) = 616バイト
27
+ となるわけです。
28
+
25
29
  今回、出力されているサイズの数値が異なっているようですので、まずはその計算を見直してはどうでしょうか。
26
30
 
27
31
  データ部
@@ -31,20 +35,20 @@
31
35
  データ部は、画像の下の行から順に出力されています。
32
36
  行の中では左から右にデータが並びます。
33
37
 
34
- 今回は7x7のデータを14x14として出力するため、各セルを行・列それぞれで2回ずつ出力しているようです。
38
+ 今回は7x7のデータを14x14として出力するため、各セルを行・列それぞれで2回ずつ出力していす。
35
- ここまでは問題なさそうですが、1行が4の倍数となるように補う部分問題ありそうです。
39
+ ここまでは問題なさそうですが、1行が4の倍数となるように補う部分問題ありそうです。
36
40
 
37
41
  コード上では
38
42
  `Palette = Palette & WorksheetFunction.Rept(" 00 00", 4 - ((3 * arg.Columns.Count * zoom) Mod 4))`
43
+ となっています。
39
- の部分ですが、上記で`4 - ((3 * arg.Columns.Count * zoom) Mod 4)`は`4 - ((3 * 7 * 2) Mod 4)`で`2`となり、" 00 00"を2回繰り返して"00 00 00 00"を付加しています。
44
+ 上記で`4 - ((3 * arg.Columns.Count * zoom) Mod 4)`は`4 - ((3 * 7 * 2) Mod 4)`で結果は`2`となります。
45
+ この結果、"00 00"を2回繰り返して"00 00 00 00"を付加しています。
40
46
 
41
- 今回補いたいのは(14列x3バイト)=42を4で割った余り2バイト分の"00 00"ですが4バイト出力してしまっています。
47
+ 今回補いたいのは(14列x3バイト)=42バイトを4で割った余り2バイト分の"00 00"なので、ここも修正が必要な個所かと思います。
42
48
 
43
- ここも修正が必要な個所かと思います。
44
-
45
49
  ---
46
50
 
47
51
  これらを修正すれば、正しい画像が出力されると思います。
48
- ※私の環境でデータ部のロジックを修正し、ヘッダ部の計算はバイナリファイル正しい値を直書きたところ、正常な画像となりました。
52
+ ※私の環境でデータ部のロジックを修正し、出力された画像ファイルをバイナリエディタで正しいファイルサイズ・データサイズに書き換えてみたところ、正常な画像となりました。
49
53
 
50
54
  頑張ってみてください。

1

修正

2018/02/19 05:38

投稿

jawa
jawa

スコア3020

answer CHANGED
@@ -20,7 +20,7 @@
20
20
  ヘッダ部は54バイト)なので、データ部は616バイトということになります。
21
21
 
22
22
  14行x14列をカラーコード3バイトで表すので、単純計算では14行 * 14列 * 3バイト = 588バイトです。
23
- しかし1行ごとに4の倍数のバイト数となるように00が補われますので、((14 * 3バイト) + 2バイト) * 14列 = 616バイトとなるわけです。
23
+ しかし1行ごとに4の倍数のバイト数となるように00が補われますので、14行 * ((14 * 3バイト) `+ 2バイト`) = 616バイトとなるわけです。
24
24
 
25
25
  今回、出力されているサイズの数値が異なっているようですので、まずはその計算を見直してはどうでしょうか。
26
26