• Anmelden

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

1

Freitag, 16. April 2010, 19:38

Apng D:

Hi,
ich wollte passend zum "Bitmap to PNG" Skript auch ein "Bitmaps to APNG"-Skript schreiben.
Hat natürlich nicht geklappt :D

Spoiler: Verändertes Bitmap to PNG

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#============================================================================
# ** Bitmap -> .PNG
#----------------------------------------------------------------------------
# www.66rpg.com
# V 1.1
# 16/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Saves a Bitmap as a .png file.
# 
# Bitmap#make_png([path])
#   Saves the Bitmap to path. Eventually given directories will be created
#   if needed.
#============================================================================
 
class Bitmap
  def make_png(path = 'like')
	Graphics.long_code do 
  	File.makedirs(File.dirname(path))
  	data = Zlib::Png_File.make_png(self)
  	if File.extname(path) != '.png'
    	path += '.png'
  	end
  	File.open(path, 'wb') do |file|
    	file.write(data)
  	end
	end
  end
end
 
module Graphics
  def self.long_code(change_frames = true, &block)
	sleeptime = 2.5
	t = Thread.new do
  	if change_frames
    	loop do
      	sleep(sleeptime)
      	Graphics.update
    	end
  	else
    	loop do
      	sleep(sleeptime)
      	Graphics.update
      	Graphics.frame_count -= 1
    	end
  	end
	end
	result = yield
	t.exit
	t = nil
	return result
  end
end
 
module Zlib
  class Png_File < GzipWriter
	def Png_File.make_png(bitmap)
  	self.open('temp.gz') do |gz|
    	gz.make_png(bitmap)
  	end
  	data = nil
  	GzipReader.open('temp.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('temp.gz')
  	return data
	end
 
	def make_png(bitmap)
  	list = [
    	Png_File.png_header,
    	Png_File.png_ihdr(bitmap),
    	Png_File.png_idat(bitmap),
    	Png_File.png_iend
  	]
  	list.each do |i|
    	write(i)
  	end
	end
 
	# Constants
	PNG_HEADER_ARRAY = [137, 80, 78, 71, 13, 10, 26, 10]
	PNG_HEADER_STRING = PNG_HEADER_ARRAY.pack('C*')
 
	IHDR_SIZE = [13].pack('N')
	IHDR_SIGN = 'IHDR'
	IHDR_DEPTH = [8].pack('C')
	IHDR_COLOR = [6].pack('C')
	IHDR_COMP = [0].pack('C')
	IHDR_FILTER = [0].pack('C')
	IHDR_INTERL = [0].pack('C')
	IHDR_WIDTHHEIGHT = Proc.new {|i| [i].pack('N')}
	IHDR_CRC = Proc.new {|i| [Zlib.crc32(i)].pack('N')}
 
	IDAT_HEADER = "\x49\x44\x41\x54"
	IDAT_COMPDATA = Proc.new {|i| Zlib::Deflate.deflate(i, 8)}
	IDAT_CRC = IHDR_CRC
	IDAT_SIZE = Proc.new {|i| [i.length].pack('N')}
 
	DATA_MAX_ARRAY = 2**28 - 5
 
	IEND_SIZE = [0].pack('N')
	IEND_SIGN = 'IEND'
	IEND_CRC = IDAT_CRC
 
	# Methods
	def self.png_header
  	return PNG_HEADER_STRING.dup
	end
 
	def self.png_ihdr(bitmap)
  	width = IHDR_WIDTHHEIGHT.call(bitmap.width)
  	height = IHDR_WIDTHHEIGHT.call(bitmap.height)
  	string = IHDR_SIGN + width + height + IHDR_DEPTH + IHDR_COLOR + IHDR_COMP + IHDR_FILTER + IHDR_INTERL
  	crc = IHDR_CRC.call(string)
  	return IHDR_SIZE + string + crc
	end
 
	def self.png_idat(bitmap)
  	cdat = IDAT_COMPDATA.call(self.png_make_bitmap_data(bitmap))
  	return IDAT_SIZE.call(cdat) + IDAT_HEADER + cdat + IDAT_CRC.call(IDAT_HEADER + cdat)
	end
 
	def self.png_make_bitmap_data(bitmap)
  	gz = Zlib::GzipWriter.open('hoge.gz')
  	w, h = bitmap.width, bitmap.height
  	data = []
  	0.upto(h) do |y|
    	data.push(0)
    	0.upto(w) do |x|
      	c = bitmap.get_pixel(x, y)
      	data.push(c.red)
      	data.push(c.green)
      	data.push(c.blue)
      	data.push(c.alpha)
      	if data.size > DATA_MAX_ARRAY
        	gz.write(data.pack('C*'))
        	data.clear
      	end
    	end
  	end
  	gz.write(data.pack('C*'))
  	data.clear
  	gz.close
 
  	GC.start
  	data = nil
  	Zlib::GzipReader.open('hoge.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('hoge.gz')
  	return data
	end
 
	def self.png_iend
  	return IEND_SIZE + IEND_SIGN + IEND_CRC.call(IEND_SIGN)
	end
  end
end
 
class File
  def File.makedirs(*dirs)
	verbose = if dirs[-1].is_a? String then false else dirs.pop end
	mode = 0755
	for dir in dirs
  	parent = dirname(dir)
  	next if parent == dir or directory? dir
  	makedirs parent unless directory? parent
  	$stderr.print "mkdir ", dir, "\n" if verbose
  	if basename(dir) != ""
    	begin
      	Dir.mkdir dir, mode
    	rescue SystemCallError
      	raise unless directory? dir
    	end
  	end
	end
  end
end
zum Lesen den Text mit der Maus markieren


Spoiler: Bitmaps to APNG

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#============================================================================
# ** Bitmaps -> .APNG
#----------------------------------------------------------------------------
# Neo-Bahamut
# V 1.0
# 16/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Requires Bitmap -> .PNG!
#----------------------------------------------------------------------------
# Bitmap.to_apng(array_of_bitmaps, options[, path])
#   array_of_bitmaps is an Array with the Bitmaps which will be converted into
#   an APNG.
#   options is a Hash defining the single frame options (see below).
#   path is optional and defines the path to the saved file.
#
# Options:
# 'plays' => Times the animation is played. 0 for infinitif.
# 'frames' => Another Hash having the frame IDs as keys and 
#         	even more hashs as values :) (see below again) (optional)
#
# Options -> Frames:
# 'time' => Time the frame is shown. (in seconds)
# 'x' / 'y' => x and y offset
# 'dispose' => Type of dispose which is used before rendering the next frame.
#   	0: Nothing is disposed.
#   	1: Cleared to full transparency.
#   	2: Changed to the prevoius content.
# 'blend' => Type of blending which is used when rendering the frame.
#   	0: Overwrites everything.
#   	1: Blends over the old frame.
#============================================================================
 
class Bitmap
  def Bitmap.to_apng(list, options, path = 'alike')
	Graphics.long_code do 
  	File.makedirs(File.dirname(path))
  	data = Zlib::APng_File.make_apng(list, options)
  	if File.extname(path) != '.png'
    	path += '.png'
  	end
  	File.open(path, 'wb') do |file|
    	file.write(data)
  	end
	end
  end
end
 
module Zlib
  class APng_File < GzipWriter
	def APng_File.make_apng(bitmaps, options)
  	self.open('temp.gz') do |gz|
    	gz.make_apng(bitmaps, options)
  	end
  	data = nil
  	GzipReader.open('temp.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('temp.gz')
  	return data
	end
 
	def make_apng(bitmaps, options)
  	list = [
    	Png_File.png_header,
    	Png_File.png_ihdr(bitmaps[0]),
    	APng_File.apng_actl(bitmaps, options),
    	APng_File.apng_fctl(bitmaps[0], options['frames'], 0),
    	Png_File.png_idat(bitmaps[0])
  	]
  	bitmaps.each_index do |n|
    	b, o = bitmaps[n], options[n]
    	list.push(APng_File.apng_fctl(bitmaps[n], options['frames'], n))
    	list.push(APng_File.apng_fdat(bitmaps[n], n))
  	end
  	list.push(Png_File.png_iend)
  	list.each do |i|
    	write(i)
  	end
	end
 
	# Methods
	def self.apng_actl(bitmaps, options)
  	[bitmaps.size, options['plays']].pack('II')
	end
 
	def self.apng_fctl(bitmap, option, n)
  	if option.nil?
    	option = EMPTY_HASH
  	else
    	option = option[n]
  	end
  	x, y, time, dis, ble = option['x'], option['y'], option['time'], option['dispose'], option['blend']
  	x ||= 0
  	y ||= 0
  	time ||= 1
  	dis ||= 0
  	ble ||= 0
  	den = 10 ** time.dec_place
  	[n, bitmap.width, bitmap.height, x, y, time*den, den, dis, ble].pack('IIIIISSCC')
	end
 
	def self.apng_fdat(bitmap, n)
  	data = Png_File.png_idat(bitmap)
  	return [n].pack('I') + data
	end
 
	# Constants
	EMPTY_HASH = Hash.new
  end
end
 
class Numeric
  def dec_place
	if self.is_a?(Integer)
  	return 0
	else
  	return self.to_s.split('.')[1].length
	end
  end
end
zum Lesen den Text mit der Maus markieren


Testcode:

Ruby Quellcode

1
2
Bitmap.to_apng([Bitmap.new('test/1')], {'plays' => 0})
exit


Die beiden Skript nochmal in Pastebin:
http://wurstinator.pastebin.com/YFBKZnrs
http://wurstinator.pastebin.com/q4RuYQgv

Quellen, aus denen ich meine Informationen bezogen habe:
http://en.wikipedia.org/wiki/APNG
https://wiki.mozilla.org/APNG_Specificat…equence_Numbers

Das Problem ist, das scheinbar irgendein paar Bytes falsch sind, da das Bild von keinem Programm angezeigt werden kann.
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

2

Samstag, 17. April 2010, 18:39

Du vergisst ein paar Chunks (acTL, fdAT) zu schreiben und IDAT auf zu oft (wie du bei den Bild bei Wikipedia siehst soll IDAT nur einmal vorkommen) . Das Bild hier wird dir die gröbsten Fehler zeigen, aber die beiden Dateien müssen nicht übereinstimmen, da bei PNG verschiedene Kompressionslevel ausgewählt werden können:Bild

ANIM1.PNG besteht aus FRAME1.PNG und FRAME2.PNG, welche du hier finden kannst. Kleine Testdaten zu haben erleichtert die Sache und ein kleiner Hex Editor ist natürlich auch fein wie du siehst ;)

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

3

Samstag, 17. April 2010, 23:20

Ok, scheinbar habe ich die Chunks nicht richtig verstanden.
Ich hab den Code jetzt etwas verändert, aber immer noch bringen die Chunks Fehler.

Der Aufbau von acTL müsste doch so sein:
Bytes 0-3: 'acTL'
Bytes 4-7: Ein Integer, der die Frameanzahl zeigt
Bytes 8-11: Ein Integer, der die Wiedergabezahl zeigt

Ruby Quellcode

1
[97, 99, 84, 76, bitmaps.size, options['plays']].pack('CCCCII')

bitmaps.size ist 1
options['plays'] ist 0

Aber es klappt nicht :(
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

4

Sonntag, 18. April 2010, 01:41

Nein, hier ist der Aufbau eines Chunks beschrieben. Du vergisst die Länge (es ist spät, aber die dürfte bei 2x unsigned long konstant 8 Byte sein) und womöglich auch die CRC-Prüfsumme (siehe Zlib.crc32).

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

5

Sonntag, 18. April 2010, 11:39

Aha, okay.
Also, bei der Windows Bild- und Faxanzeige wird jetzt der erste Frame angezigt, wie es sein sollte ^^
Aber Firefox sagt immer, dass die Datei Fehler enthält.

Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#============================================================================
# ** Bitmaps -> .APNG
#----------------------------------------------------------------------------
# Neo-Bahamut
# V 1.0
# 16/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Requires Bitmap -> .PNG!
#----------------------------------------------------------------------------
# Bitmap.to_apng(array_of_bitmaps, options[, path])
#   array_of_bitmaps is an Array with the Bitmaps which will be converted into
#   an APNG.
#   options is a Hash defining the single frame options (see below).
#   path is optional and defines the path to the saved file.
#
# Options:
# 'plays' => Times the animation is played. 0 for infinitif.
# 'frames' => Another Hash having the frame IDs as keys and 
#         	even more hashs as values :) (see below again) (optional)
#
# Options -> Frames:
# 'time' => Time the frame is shown. (in seconds)
# 'x' / 'y' => x and y offset
# 'dispose' => Type of dispose which is used before rendering the next frame.
#   	0: Nothing is disposed.
#   	1: Cleared to full transparency.
#   	2: Changed to the prevoius content.
# 'blend' => Type of blending which is used when rendering the frame.
#   	0: Overwrites everything.
#   	1: Blends over the old frame.
#============================================================================
 
class Bitmap
  def Bitmap.to_apng(list, options, path = 'alike')
	Graphics.long_code do 
  	File.makedirs(File.dirname(path))
  	data = Zlib::APng_File.make_apng(list, options)
  	if File.extname(path) != '.png'
    	path += '.png'
  	end
  	File.open(path, 'wb') do |file|
    	file.write(data)
  	end
	end
  end
end
 
module Zlib
  class APng_File < GzipWriter
	def APng_File.make_apng(bitmaps, options)
  	self.open('temp.gz') do |gz|
    	gz.make_apng(bitmaps, options)
  	end
  	data = nil
  	GzipReader.open('temp.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('temp.gz')
  	return data
	end
 
	def make_apng(bitmaps, options)
  	if bitmaps.size == 1
    	self.write(Png_File.png_header)
    	self.write(Png_File.png_ihdr(bitmaps[0]))
    	self.write(Png_File.png_idat(bitmaps[0]))
    	self.write(Png_File.png_iend)
    	return
  	end
  	list = [
    	Png_File.png_header,
    	Png_File.png_ihdr(bitmaps[0]),
    	APng_File.apng_actl(bitmaps, options),
    	APng_File.apng_fctl(bitmaps[0], options['frames'], 0),
    	Png_File.png_idat(bitmaps[0])
  	]
  	rest = bitmaps[1, bitmaps.size-1]
  	rest.each_index do |n|
    	b, o = bitmaps[n], options[n]
    	list.push(APng_File.apng_fctl(bitmaps[n], options['frames'], n))
    	list.push(APng_File.apng_fdat(bitmaps[n], n))
  	end
  	list.push(Png_File.png_iend)
  	list.each do |i|
    	write(i)
  	end
	end
 
	# Methods
	def self.make_chunk(type, data)
  	size = [data.byte_size].pack('N')
  	crc = [Zlib.crc32(type + data)].pack('N')
  	return size + type + data + crc
	end
 
	def self.apng_actl(bitmaps, options)
  	data = [bitmaps.size, options['plays']].pack('NN')
  	self.make_chunk('acTL', data)
	end
 
	EMPTY_HASH = Hash.new
	def self.apng_fctl(bitmap, options, n)
  	option = options.nil? ? EMPTY_HASH : options[n]
  	x = option['x']; x ||= 0
  	y = option['y']; y ||= 0
  	time = option['time']; time ||= 1
  	dis = option['dis']; dis ||= 0
  	ble = option['ble']; ble ||= 0
  	den = 10 ** time.dec_place
  	data = [n, bitmap.width, bitmap.height, x, y,
          	time*den, den, dis, ble].pack('NNNNNSSCC')
  	self.make_chunk('fcTL', data)
	end
 
	def self.apng_fdat(bitmap, n)
  	mdat = Png_File.png_make_bitmap_data(bitmap)
  	data = Zlib::Deflate.deflate(mdat, 8)
  	self.make_chunk('fdAT', [n].pack('N') + data)
	end
  end
end
 
class Numeric
  def dec_place
	if self.is_a?(Integer)
  	return 0
	else
  	return self.to_s.split('.')[1].length
	end
  end
end
zum Lesen den Text mit der Maus markieren


Ich glaub, dass hat was mit fdAT zu tun, weil ich nicht so wirklich weiß, was ich da alles komprimieren soll...
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

6

Montag, 19. April 2010, 01:01

Ich hab's mir nicht näher angesehen, da das Skript "Bitmap -> .PNG" bei mir fehlerhafte PNGs erstellt. Die Basis deines Skripts hat also schon einen Bug. Hier findest du ein viel schöner geschriebenes Skript, welches Bitmaps als PNG abspeichern kann. Nimm das als Vorlage/-bild (Code, wenn sinnvoll, in Methoden auslagern) und schreib das APNG-Skript neu. Auch wenn es im Großen und Ganzen passt, aber an einer Ruine (das 66rpg.com-Skript ist schlecht geschrieben und in deer von die geposteten Version funktioniert es auch nicht) herumbasteln statt von Grund auf noch mal ein neues zu eschreib, in das du das vorher erworbene Wissen einfließen lassen kannst. Das ist nur ein Tipp meinerseits, du kannst also ruhig "Nein." sagen.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

7

Montag, 19. April 2010, 07:18

Ich hatte es schon vorher verbessert (lustigerweise ähnlich wie es bei deinem Link ist :), aber Animationen klappen trotzdem nicht :p

Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#============================================================================
# ** Bitmap -> .PNG
#----------------------------------------------------------------------------
# www.66rpg.com & Neo-Bahamut
# V 1.1.2
# 18/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Saves a Bitmap as a .png file.
# 
# Bitmap#make_png([path])
#   Saves the Bitmap to path. Eventually given directories will be created
#   if needed.
#============================================================================
 
class Bitmap
  def make_png(path = 'like')
	Graphics.long_code do 
  	File.makedirs(File.dirname(path))
  	data = Zlib::Png_File.make_png(self)
  	if File.extname(path) != '.png'
    	path += '.png'
  	end
  	File.open(path, 'wb') do |file|
    	file.write(data)
  	end
	end
  end
end
 
module Graphics
  def self.long_code(change_frames = true, &block)
	sleeptime = 2.5
	t = Thread.new do
  	if change_frames
    	loop do
      	sleep(sleeptime)
      	Graphics.update
    	end
  	else
    	loop do
      	sleep(sleeptime)
      	Graphics.update
      	Graphics.frame_count -= 1
    	end
  	end
	end
	result = yield
	t.exit
	t = nil
	return result
  end
end
 
class String
  def byte_size
	unpack('C*').size
  end
  alias_method :byte_length, :byte_size
end
 
module Zlib
  class Png_File < GzipWriter
	def Png_File.make_png(bitmap)
  	self.open('temp.gz') do |gz|
    	gz.make_png(bitmap)
  	end
  	data = nil
  	GzipReader.open('temp.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('temp.gz')
  	return data
	end
 
	def make_png(bitmap)
  	list = [
    	Png_File.png_header,
    	Png_File.png_ihdr(bitmap),
    	Png_File.png_idat(bitmap),
    	Png_File.png_iend
  	]
  	list.each do |i|
    	write(i)
  	end
	end
 
	# Methods
	def self.make_chunk(type, data)
  	size = [data.byte_size].pack('N')
  	crc = [Zlib.crc32(type + data)].pack('N')
  	return size + type + data + crc
	end
 
	PNG_HEADER = [137, 80, 78, 71, 13, 10, 26, 10].pack('C*')
	def self.png_header
  	PNG_HEADER
	end
 
	def self.png_ihdr(bitmap)
  	data = [bitmap.width, bitmap.height, 8, 6, 0, 0, 0].pack('NNCCCCC')
  	return self.make_chunk('IHDR', data)
	end
 
	def self.png_idat(bitmap)
  	data = self.png_make_bitmap_data(bitmap)
  	return self.make_chunk('IDAT', Zlib::Deflate.deflate(data, 8))
	end
 
	DATA_MAX_ARRAY = 2**28 - 5
	def self.png_make_bitmap_data(bitmap)
  	gz = Zlib::GzipWriter.open('hoge.gz')
  	w, h = bitmap.width-1, bitmap.height-1
  	data = []
  	0.upto(h) do |y|
    	data.push(0)
    	0.upto(w) do |x|
      	c = bitmap.get_pixel(x, y)
      	data.push(c.red)
      	data.push(c.green)
      	data.push(c.blue)
      	data.push(c.alpha)
      	if data.size > DATA_MAX_ARRAY
        	gz.write(data.pack('C*'))
        	data.clear
      	end
    	end
  	end
  	gz.write(data.pack('C*'))
  	data.clear
  	gz.close
 
  	GC.start
  	data = nil
  	Zlib::GzipReader.open('hoge.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('hoge.gz')
  	return data
	end
 
	def self.png_iend
  	return self.make_chunk('IEND', '')
	end
  end
end
 
class File
  def File.makedirs(*dirs)
	verbose = if dirs[-1].is_a? String then false else dirs.pop end
	mode = 0755
	for dir in dirs
  	parent = dirname(dir)
  	next if parent == dir or directory? dir
  	makedirs parent unless directory? parent
  	$stderr.print "mkdir ", dir, "\n" if verbose
  	if basename(dir) != ""
    	begin
      	Dir.mkdir dir, mode
    	rescue SystemCallError
      	raise unless directory? dir
    	end
  	end
	end
  end
end
zum Lesen den Text mit der Maus markieren
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

8

Montag, 19. April 2010, 21:12

1. Problem: Sequenznummern
Ein mit diesem Skript erstellte APNG mit 3 Frames sollte so aussehen:
PNG-Header -> acTL -> fcTL (Nr. 0) -> IDAT -> fcTL (Nr. 1) -> fdAT (Nr. 2) -> fcTL (Nr. 3) -> fdAT (Nr. 4) -> IEND
So ist es derzeit:
PNG-Header -> acTL -> fcTL (Nr. 0) -> IDAT -> fcTL (Nr. 1) -> fdAT (Nr. 2) -> fcTL (Nr. 2) -> fdAT (Nr. 3) -> IEND

2. Problem: make_apng
So wie ich das sehe wird das falsche Bitmap (der 1. Frame, der bereits geschrieben wurde (IDAT)) wird nochmals als 2. Frame geschrieben, etc.) genommen:

Ruby Quellcode

1
2
3
rest = bitmaps[1, bitmaps.size-1]
rest.each_index do |n|
  b, o = bitmaps[n], options[n]   # es wird bitmap[0] genommen und nicht rest[0], bitmap[1] / each_with_index  verwenden?


3. Problem: fcTL chunk
Ich müsste die Doku mir noch mal ansehen, aber das dürfte eigentlich so passen bis auf eine Kleinigkeit: im String SS durch nn oder n2 ersetzen.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

9

Montag, 19. April 2010, 22:46

3 war richtig (die beiden Zahlen wurden ja als unsigned Shots beschrieben), aber Punkte 1 und 2 hab ich jetzt verbessert und es klappt.

Vielen Dank, Cremno, wer weiß, ob ich es ohne dich geschafft hätte? :D

Und hier das Ergebnis, für das sich die ganze Mühe ja wohl gelohnt hat xD"
Bild
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

10

Montag, 19. April 2010, 23:25

Zitat von »Neo-Bahamut«

3 war richtig (die beiden Zahlen wurden ja als unsigned Shots beschrieben)

Zitat von »https://wiki.mozilla.org/APNG_Specification#Terminology«

an "unsigned short" shall be a 16-bit unsigned integer in network byte order [...]
S ist aber unter Windows Little Endian und nicht Network-/Big Endian, n jedoch:

Zitat von »Ruby Doku«

n | Short, network (big-endian) byte-order
Immer schön an die Spezifikation halten :)

Ansonsten Glückwunsch zum funktionieren Skript!

11

Dienstag, 20. April 2010, 05:56

du könntest ja gleich wieder dafür sorgen das Bitmap und weitere instance variabeln gemashalt werden können ...
wenn ein objekt nicht gemashalt werden kann, geht mir das gewaltig auf den Keks ...
(weil procs nicht save bar sind, musste ich einige meiner engines umschreiben)
Realität ist nur eine subjektive Wahrnehmungsstörung.

Alles ist wahr, wenn man für wahr einen bestimmten Wert annimmt.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

12

Dienstag, 20. April 2010, 06:35

@Cremno: Wo ist denn der überhaupt der Unterschied zwischen "network byte order" und... dem anderen?
Weil mit S klappts ja auch^^"

@ Hanmac: Das ist ein anderes Thema, aber Proc zu "marshalen" geht nicht :p
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

13

Dienstag, 20. April 2010, 14:54

du könntest das png und apng mal im main post aktualisieren (man könnte es noch ein wenig verbessern)

@mashal: genau das war ja das problem
auserdem das ich probleme hatte wenn ich meine game items und rpg items gespeichert hatte, waren die rpg items die sich in den game items nich befanden nicht mehr gleich mit den rpg items die ich extra gespeichert hatte (aber das hab ich gefixt)
Realität ist nur eine subjektive Wahrnehmungsstörung.

Alles ist wahr, wenn man für wahr einen bestimmten Wert annimmt.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

14

Dienstag, 20. April 2010, 17:25

PNG ist oben schon :p
Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#============================================================================
# ** Bitmaps -> .APNG
#----------------------------------------------------------------------------
# Neo-Bahamut
#   thanks to Cremno for debugging
# V 1.0
# 19/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Requires Bitmap -> .PNG!
#----------------------------------------------------------------------------
# Bitmap.to_apng(array_of_bitmaps, options[, path])
#   array_of_bitmaps is an Array with the Bitmaps which will be converted into
#   an APNG.
#   options is a Hash defining the single frame options (see below).
#   path is optional and defines the path to the saved file.
#
# Options:
# 'plays' => Times the animation is played. 0 for infinitif.
# 'frames' => Another Hash having the frame IDs as keys and 
#         	even more hashs as values :) (see below again) (optional)
#
# Options -> Frames:
# 'time' => Time the frame is shown. (in seconds)
# 'x' / 'y' => x and y offset
# 'dispose' => Type of dispose which is used before rendering the next frame.
#   	0: Nothing is disposed.
#   	1: Cleared to full transparency.
#   	2: Changed to the prevoius content.
# 'blend' => Type of blending which is used when rendering the frame.
#   	0: Overwrites everything.
#   	1: Blends over the old frame.
#============================================================================
 
class Bitmap
  def Bitmap.to_apng(list, options, path = 'alike')
	Graphics.long_code do 
  	File.makedirs(File.dirname(path))
  	data = Zlib::APng_File.make_apng(list, options)
  	if File.extname(path) != '.png'
    	path += '.png'
  	end
  	File.open(path, 'wb') do |file|
    	file.write(data)
  	end
	end
  end
end
 
module Zlib
  class APng_File < GzipWriter
	def APng_File.make_apng(bitmaps, options)
  	self.open('temp.gz') do |gz|
    	gz.make_apng(bitmaps, options)
  	end
  	data = nil
  	GzipReader.open('temp.gz') do |gz|
    	data = gz.read
  	end
  	File.delete('temp.gz')
  	return data
	end
 
	def make_apng(bitmaps, options)
  	if bitmaps.size == 1
    	self.write(Png_File.png_header)
    	self.write(Png_File.png_ihdr(bitmaps[0]))
    	self.write(Png_File.png_idat(bitmaps[0]))
    	self.write(Png_File.png_iend)
    	return
  	end
  	list = [
    	Png_File.png_header,
    	Png_File.png_ihdr(bitmaps[0]),
    	APng_File.apng_actl(bitmaps, options),
    	APng_File.apng_fctl(bitmaps[0], options['frames'], 0, 0),
    	Png_File.png_idat(bitmaps[0])
  	]
  	1.upto(bitmaps.size-1) do |n|
    	b, o = bitmaps[n], options[n]
    	list.push(APng_File.apng_fctl(bitmaps[n], options['frames'], n, n*2-1))
    	list.push(APng_File.apng_fdat(bitmaps[n], n*2))
  	end
  	list.push(Png_File.png_iend)
  	list.each do |i|
    	write(i)
  	end
	end
 
	# Methods
	def self.make_chunk(type, data)
  	size = [data.byte_size].pack('N')
  	crc = [Zlib.crc32(type + data)].pack('N')
  	return size + type + data + crc
	end
 
	def self.apng_actl(bitmaps, options)
  	data = [bitmaps.size, options['plays']].pack('NN')
  	self.make_chunk('acTL', data)
	end
 
	EMPTY_HASH = Hash.new
	def self.apng_fctl(bitmap, options, n, seqnum)
  	option = (options.nil? || options[n].nil?) ? EMPTY_HASH : options[n]
  	x = option['x']; x ||= 0
  	y = option['y']; y ||= 0
  	time = option['time']; time ||= 1
  	dis = option['dis']; dis ||= 0
  	ble = option['ble']; ble ||= 0
  	den = 10 ** time.dec_place
  	data = [seqnum, bitmap.width, bitmap.height, x, y,
          	time*den, den, dis, ble].pack('NNNNNSSCC')
  	self.make_chunk('fcTL', data)
	end
 
	def self.apng_fdat(bitmap, seqnum)
  	mdat = Png_File.png_make_bitmap_data(bitmap)
  	data = Zlib::Deflate.deflate(mdat, 8)
  	self.make_chunk('fdAT', [seqnum].pack('N') + data)
	end
  end
end
 
class Numeric
  def dec_place
	if self.is_a?(Integer)
  	return 0
	else
  	return self.to_s.split('.')[1].length
	end
  end
end
zum Lesen den Text mit der Maus markieren
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

15

Dienstag, 20. April 2010, 21:01

ich hab deins mal ein ein *klein wenig* abgeändert :verrückt:

sag nur wenn du fragen hast

Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#============================================================================
# ** Bitmap -> .PNG
#----------------------------------------------------------------------------
# www.66rpg.com & Neo-Bahamut
# V 1.1.2
# 18/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Saves a Bitmap as a .png file.
# 
# Bitmap#make_png([path])
#   Saves the Bitmap to path. Eventually given directories will be created
#   if needed.
#============================================================================
 
class Bitmap
  def make_png(path)
    Graphics.long_code do 
      File.makedirs(File.dirname(path))
      path.concat('.png') if File.extname(path) != '.png'
      File.open(path, 'wb') { |file| file.write(Zlib::Png_File.make_png(self)) }
    end
  end
end
 
module Graphics
  def self.long_code(change_frames = true, &block)
    sleeptime = 2.5
    t = Thread.new do
      if change_frames
        loop do
          sleep(sleeptime)
          Graphics.update
        end
      else
        loop do
          sleep(sleeptime)
          Graphics.update
          Graphics.frame_count -= 1
        end
      end
    end
    result = yield
    t.exit
    t = nil
    return result
  end
end
 
module Zlib
  class Png_File < GzipWriter
    def self.make_png(bitmap)
      self.open('temp.gz') { |gz| gz.make_png(bitmap) }
      data = GzipReader.open('temp.gz') { |gz| gz.read }
      File.delete('temp.gz')
      return data
    end
 
    def make_png(bitmap)
      list = [
        png_header,
        png_ihdr(bitmap),
        png_idat(bitmap),
        png_iend
      ]
      list.each { |i| write(i) }
    end
 
    # Methods
    def make_chunk(type, data)
      return [data.unpack('C*').size].pack('N') + type + data + [Zlib.crc32(type + data)].pack('N')
    end
 
    def png_header
      return "\211PNG\r\n\032\n" #png_header
    end
 
    def png_ihdr(bitmap)
      data = [bitmap.width, bitmap.height, 8, 6, 0, 0, 0].pack('NNCCCCC')
      return make_chunk('IHDR', data)
    end
 
    def png_idat(bitmap)
      data = png_make_bitmap_data(bitmap)
      return make_chunk('IDAT', Zlib::Deflate.deflate(data, 8))
    end
 
    def png_make_bitmap_data(bitmap)
      Zlib::GzipWriter.open('hoge.gz') do |gz|
        data = []
        bitmap.height.times do |y|
          data.push(0)
          bitmap.width.times do |x|
            c = bitmap.get_pixel(x, y)
            data.push(c.red,c.green,c.blue,c.alpha)
            if data.size > 268435451 #DATA_MAX_ARRAY
              gz.write(data.pack('C*'))
              data.clear
            end
          end
        end
        gz.write(data.pack('C*'))
      end
 
      GC.start
      data = Zlib::GzipReader.open('hoge.gz') { |gz| gz.read }
      File.delete('hoge.gz')
      return data
    end
 
    def png_iend
      return make_chunk('IEND', '')
    end
  end
end
 
class File
  def self.makedirs(*dirs)
    verbose = if dirs[-1].is_a? String then false else dirs.pop end
    mode = 0755
    for dir in dirs
      parent = dirname(dir)
      next if parent == dir or directory? dir
      makedirs parent unless directory? parent
      $stderr.print "mkdir ", dir, "\n" if verbose
      if basename(dir) != ""
        begin
          Dir.mkdir dir, mode
        rescue SystemCallError
          raise unless directory? dir
        end
      end
    end
  end
end
zum Lesen den Text mit der Maus markieren


Spoiler

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#============================================================================
# ** Bitmaps -> .APNG
#----------------------------------------------------------------------------
# Neo-Bahamut
#   thanks to Cremno for debugging
# V 1.0
# 19/04/2010 (DD/MM/YYYY)
#----------------------------------------------------------------------------
# Requires Bitmap -> .PNG!
#----------------------------------------------------------------------------
# Bitmap.to_apng(array_of_bitmaps, options[, path])
#   array_of_bitmaps is an Array with the Bitmaps which will be converted into
#   an APNG.
#   options is a Hash defining the single frame options (see below).
#   path is optional and defines the path to the saved file.
#
# Options:
# 'plays' => Times the animation is played. 0 for infinitif.
# 'frames' => Another Hash having the frame IDs as keys and 
#           even more hashs as values :) (see below again) (optional)
#
# Options -> Frames:
# 'time' => Time the frame is shown. (in seconds)
# 'x' / 'y' => x and y offset
# 'dispose' => Type of dispose which is used before rendering the next frame.
#     0: Nothing is disposed.
#     1: Cleared to full transparency.
#     2: Changed to the prevoius content.
# 'blend' => Type of blending which is used when rendering the frame.
#     0: Overwrites everything.
#     1: Blends over the old frame.
#============================================================================
 
class Bitmap
  def self.to_apng(list, path, options = {} )
    Graphics.long_code do 
    	File.makedirs(File.dirname(path))
    	path.concat('.png') if File.extname(path) != '.png'
    	File.open(path, 'wb') { |file| file.write(Zlib::APng_File.make_apng(list, options)) }
    end
  end
  def to_apng(path,options = {} )
    Bitmap.to_apng([self], path,options)
  end
end
 
module Zlib
  class APng_File < Png_File
  def self.make_apng(bitmaps, options)
    self.open('temp.gz') { |gz| gz.make_apng(bitmaps, options) }
    data = GzipReader.open('temp.gz') { |gz| gz.read }
    File.delete('temp.gz')
    return data
  end
 
  def make_apng(bitmaps, options)
    return make_png(bitmaps[0])) if bitmaps.size == 1
    bitmap = bitmaps.shift
    options['frames'] ||={}
    list = [
    	png_header,
    	png_ihdr(bitmap),
    	apng_actl(bitmap, options['plays'] || 0),
    	apng_fctl(bitmap, options['frames'][0], 0),
    	png_idat(bitmap)
    ]
    bitmaps.each_with_index { |b,n| list.push(apng_fctl(b, options['frames'][n], n*2-1),apng_fdat(b, n*2))}
    list.push(png_iend)
    list.each { |i| write(i) }
    end
  end
 
  # Methods
  def apng_actl(bitmaps, plays)
    return make_chunk('acTL', [bitmaps.size, plays].pack('NN'))
  end
 
  def apng_fctl(bitmap, option, seqnum)
    option ||= {}
    x = option['x'] || 0
    y = option['y'] || 0
    time = option['time'] || 1
    dis = option['dis'] || 0
    ble = option['ble'] || 0
    den = 10 ** [(time % 1).to_s.size - 2,0].max
    data = [seqnum, bitmap.width, bitmap.height, x, y,
            time*den, den, dis, ble].pack('NNNNNSSCC')
    return make_chunk('fcTL', data)
  end
 
  def apng_fdat(bitmap, seqnum)
    mdat = png_make_bitmap_data(bitmap)
    data = Zlib::Deflate.deflate(mdat, 8)
    return make_chunk('fdAT', [seqnum].pack('N') + data)
  end
end
zum Lesen den Text mit der Maus markieren
Realität ist nur eine subjektive Wahrnehmungsstörung.

Alles ist wahr, wenn man für wahr einen bestimmten Wert annimmt.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

16

Dienstag, 20. April 2010, 21:25

Zitat

sag nur wenn du fragen hast
Was hast du denn geändert? ^^
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

17

Dienstag, 20. April 2010, 21:42

das solltest du schon sehen wie zb APng_File eine tochter von pngfile ist
und die methoden sind alle instance methoden anstatt klassen methoden

verkürzen des codes durch ausnutzung der rückgabe werte von procs
nutzen anderer funktionen anstatt die für numeric oder string

und ein wenig optimierung
zb concat anstatt +=""
push(x,y) anstatt mehrere push
x = option['x'] || 0 anstatt x = option['x']; x ||= 0
each_with_index anstatt mit variabeln die NICHT genutzt werden
(und weiteres)
Realität ist nur eine subjektive Wahrnehmungsstörung.

Alles ist wahr, wenn man für wahr einen bestimmten Wert annimmt.

Neo-Bahamut

Himmelsgleicher

  • »Neo-Bahamut« ist der Autor dieses Themas

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

18

Dienstag, 20. April 2010, 22:31

Zitat

das solltest du schon sehen wie zb APng_File eine tochter von pngfile ist
und die methoden sind alle instance methoden anstatt klassen methoden
Das hab ich absichtlich so gemacht ._.

Zitat

verkürzen des codes durch ausnutzung der rückgabe werte von procs
Wo benutzt du denn Procs? Oo

Zitat

nutzen anderer funktionen anstatt die für numeric oder string
Du hast doch jetzt nur die Methodenaufrufe durch den direkten Code ersetzt, oder nicht?
Dafür gibts doch Methoden ._.

Zitat

push(x,y) anstatt mehrere push
x = option['x'] || 0 anstatt x = option['x']; x ||= 0
Hab ich übernommen.

Zitat

concat anstatt +=""
Ist nicht gut, das eine mal wo ich String += Anderer String mache, ist bei Bitmap#make_png bzw Bitmap#to_apng und ich will ja nicht einfach den Parameter ändern.

Zitat

each_with_index anstatt mit variabeln die NICHT genutzt werden
Keine Ahnung, warum ich die beiden Variablen da noch hatte ^^"
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

19

Dienstag, 20. April 2010, 22:53

Zitat

Das hab ich absichtlich so gemacht ._.

ich find da lässt sich streiten, als instanc funktionieren die genauso wie als klasse

und wieso Apng nicht tochter von png?

Zitat

verkürzen des codes durch ausnutzung der rückgabe werte


deins:

Ruby Quellcode

1
2
3
4
data = nil
Zlib::GzipReader.open('hoge.gz') do |gz|
data = gz.read
end

meins:

Ruby Quellcode

1
data = Zlib::GzipReader.open('hoge.gz') { |gz| gz.read }

mit proc meine ich die blöcke {} die haben wie alles einen rückgabe wert den man wiederum nutzen kann


dec_place, und byte_size
habe ich gegen andere funktion ersetzt weil ich mir dacht das man die nicht unbedingt gut in numeric passt ...

Zitat

ich will ja nicht einfach den Parameter ändern.

Zitat


ok seh ich ein, aber in dem fall muss man abwegen ob es da eine rolle spielt


PS: woran ich morgen arbeite (unteranderem):
make_apng soll auch array von rect als parameter akzeptieren (und vllt noch ein zweites rect)
so kann man ein bitmap in ein apng umwandeln indem es die auschnitte anzeigt
Realität ist nur eine subjektive Wahrnehmungsstörung.

Alles ist wahr, wenn man für wahr einen bestimmten Wert annimmt.

20

Mittwoch, 21. April 2010, 00:02

Zitat

@Cremno: Wo ist denn der überhaupt der Unterschied zwischen "network byte order" und... dem anderen?
Weil mit S klappts ja auch^^"
Little-Endian und Big-Endian sind die Bytereihenfolge, also ob du die Bytes von "links" nach "rechts" oder andersherum schreibst. Oder anders: Big-Endian heißt du schreibst das höherwertige Byte zuerst, bei Little-Endian eben das niederwertige Byte zuerst.

Zitat

du könntest ja gleich wieder dafür sorgen das Bitmap und weitere instance variabeln gemashalt werden können ...
wenn ein objekt nicht gemashalt werden kann, geht mir das gewaltig auf den Keks ...
Dann ist das imo ein Fehler in deinem Design. Bitmaps gehören nicht gemarshalt.

Zitat

auserdem das ich probleme hatte wenn ich meine game items und rpg items gespeichert hatte, waren die rpg items die sich in den game items nich befanden nicht mehr gleich mit den rpg items die ich extra gespeichert hatte (aber das hab ich gefixt)
Genau das ist das Problem. Es hat schon seinen Sinn warum in der RGSS immer nur der Index eines Items, und nicht die Referenz auf das Item selbst, abgespeichert wird. Man sollte imo schon eine klare Grenze ziehen zwischen eingelesenen, konstanten Daten und Konfigurationen, Ingame-Grafiken und veränderlichen Spielmodellen. Wenn man nur letzteres per Marshal serialisiert und die anderen Dinge jedes Mal neu einliest und aufbaut, kommt man erst gar nicht zu solchen Problemen.

Zitat

Ist nicht gut, das eine mal wo ich String += Anderer String mache, ist bei Bitmap#make_png bzw Bitmap#to_apng und ich will ja nicht einfach den Parameter ändern.

Sehe ich auch so. Parameter sollte man möglichst nicht modifizieren, es sei denn es kostet wirklich spürbar Performance. Aber das ist hier ja nicht der Fall.

Ruby Quellcode

1
2
3
4
5
6
class String
  def byte_size
	unpack('C*').size
  end
  alias_method :byte_length, :byte_size
end

Solange du mit Ruby 1.8 arbeitest sollte String#size dir bereits die Bytelänge eines Strings geben.
Bild
RMXP Grundkurs
1 2 3
Ruby/RGSS-Kurs

Social Bookmarks