Cara... não itendi nada iso da pra stari as imagens da tibia.spr ? pq aki ja abaixei 2 tpw de tibia.spr os dois da erro =(
- Fórum
- xTibia - Notícias e Suporte
- Soluções
- Archived
- Spr Extractor
info
Grupo: Campones
Registrado: 03/11/12
Posts: 2
Reputação: 0
Char no Tibia: Demoliatonr

info
Grupo: Cavaleiro
Registrado: 22/10/11
Posts: 193
Reputação: +32
Char no Tibia: _l_

Reportado por reviver um tópico com mais de 30 dias sem um post.
info
Grupo: Herói
Registrado: 28/11/10
Posts: 3.4k
Reputação: +585
Gênero: Masculino

Cara... não itendi nada iso da pra stari as imagens da tibia.spr ? pq aki ja abaixei 2 tpw de tibia.spr os dois da erro =(
Leia as regras do xtibia.com antes de postar, apos se registrar você aceito tais termos!
Caso ficar quebrando as, sera alertado!
Ultimo aviso!
Cara... não itendi nada iso da pra stari as imagens da tibia.spr ? pq aki ja abaixei 2 tpw de tibia.spr os dois da erro =(
me fale quais erros dão, e quais versões você tentou usar, versoes mais recentes tiveram uma pequena mudança na estrutura do spr, no arranjo de bytes onde grava o numero de sprites no spr, cresceu dois bytes se não me engano
Cara... não itendi nada iso da pra stari as imagens da tibia.spr ? pq aki ja abaixei 2 tpw de tibia.spr os dois da erro =(
Leia as regras do xtibia.com antes de postar, apos se registrar você aceito tais termos!
Caso ficar quebrando as, sera alertado!
Ultimo aviso!
Poderia me mostrar onde especificamente está escrito que não se pode postar em tópicos com mais de 30 dias de inatividade?
E mesmo que haja de fato isso escrito em algum lugar, o usuario maiconui apenas queria esclarecer uma duvida, que mal há nisso?
Unico aviso que vi foi esse:
Cuidado, XTibiano!
dalvorsn, o último post deste tópico tem mais de 30 dias e uma nova postagem agora poderá ser considerada como flood! Consideramos flood comentários sem sentido só para fazer o tópico subir na posição! Fique ligado e ajude a manter um fórum limpo!
E ele é bem claro, diz respeito a flood.





info
Grupo: Conde
Registrado: 21/12/11
Posts: 750
Reputação: +268
Gênero: Masculino
Sprite Extractor
O sistema é composto de dois arquivos:
# readBytes.lua
dofile("./SpriteReader.lua") function convert(num, count) local array = {} local aux = 0 for i = count, 2, -1 do local val = math.floor(num/(256^(i-1))) array[i] = val num = num - (val*(256^(i-1))) end array[1] = num return unpack(array) end function saveBMP(filename, width, height, pixels) sizeArrayColors = 4 * width * height size_1, size_2, size_3, size_4 = convert(sizeArrayColors+54, 4) width_1, width_2, width_3, width_4 = convert(width, 4) height_1, height_2, height_3, height_4 = convert(height, 4) size_array_1, size_array_2, size_array_3, size_array_4 = convert(sizeArrayColors, 4) local byteArray = { --bmp header 0x42, 0x4D, -- magic numbers size_1, size_2, size_3, size_4, --0x00, 0x12, 0x00, 0x00, -- tamanho em bytes da imagem (3072) 0x00, 0x00, 0x00, 0x00, -- sem uso 0x36, 0x00, 0x00, 0x00, -- endereço de onde começam as cores --dib header 0x28, 0x00, 0x00, 0x00, -- tamanho do dib header em bytes - 40 width_1, width_2, width_3, width_4, -- largura height_1, height_2, height_3, height_4, -- altura 0x01, 0x00, 0x18, 0x00, -- numero de bits por pixel (24bits/pixel) 0x00, 0x00, 0x00, 0x00, size_array_1, size_array_2, size_array_3, size_array_4, -- numeros de bytes no array de cores 0x13, 0x0B, 0x00, 0x00, -- resolução horizontal bit/meter 0x13, 0x0B, 0x00, 0x00, -- resolução horizontal bit/meter 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } local file = io.open(filename..".bmp", "w+b") for _, byte in pairs(byteArray) do file:write(type(byte) == "number" and string.char(byte) or byte) end for y = height , 1, -1 do for x = 1, width do for _, byte in pairs(pixels[x][y]) do file:write(string.char(byte)) end end end file:close() end function main() local file = io.open("./Tibia.spr", "rb") if(file)then reader = SpriteReader:load(file) reader.version = reader:getUint32() reader.numberOfSprites = reader:getUint16() io.write("Version: ",reader.version,"\nNumber Of Sprites: ", reader.numberOfSprites, "\n") if not(type(io.open("./Sprites")) == "userdata")then os.execute("mkdir Sprites") end print "Extraindo, aguarde ..." for id = 1, reader.numberOfSprites do --print("Extraindo: "..id.."/"..reader.numberOfSprites) saveBMP("./Sprites/"..tostring(id), 32, 32, reader:getPixelsData(id)) end print("Tempos gasto na extração: "..os.clock()) reader:closeData() else print("Arquivo .spr não encontrado") end end main()# SpriteReader.lua
SpriteReader = {} --[[ * Inicia classe com atributo do tipo userdata 'data' * Seta atributos default e le data no modo "*a" --]] function SpriteReader:load(data) attr = {version = 0, numberOfSprites = 0, posByte = 1,file = data, data = data:read("*a"), id = 1} return setmetatable(attr, {__index = self}) end --[[ * Pega os valores minimo e maximos para numero de bytes fornecidos * signed é uma variavel boolean, quando true rearranja os limites para tipo signed --]] function SpriteReader:getRanges(byte, signed) local min, max = 0, ((256^byte) -1) if(signed)then min = -max/2 max = max/2 end return min, max end --[[ * le byte a byte somando seus valores 'byte' numero de vezes * se signed é true, reajusta o valor para signed --]] function SpriteReader:readBytes(byte, signed) local min, _ = self:getRanges(byte, signed) local value = 0 for var = 1, byte do value = value + ( self:nextByte() * (256^(var-1)) ) end return value + min end --[[ * le 'posByte', que é um atributo de controle, serve apaenas para armazenar o proximo byte * reajusta 'posByte' para posição seguinte * retorna 'byte' --]] function SpriteReader:nextByte() local byte = self.data:byte(self.posByte) self.posByte = self.posByte + 1 return tonumber(byte) end function SpriteReader:seek(offset) self.posByte = offset + 1 end --[[ * faz a leitura byte a byte 8 vezes somando seus valores pela progressão: * (byte) ^ 1 + (byte) ^ 2 + ... + (byte) ^ n * valido para todos unsigneds abaixo --]] function SpriteReader:getUint64() return self:readBytes(8, false) end function SpriteReader:getUint32() return self:readBytes(4, false) end function SpriteReader:getUint16() return self:readBytes(2, false) end function SpriteReader:getUint8() return self:readBytes(1, false) end --[[ * segue a mesma lógica anterior, com uma unica diferença * o valor final é reajustado para signed --]] function SpriteReader:getInt64() return self:readBytes(8, true) end function SpriteReader:getInt32() return self:readBytes(4, true) end function SpriteReader:getInt16() return self:readBytes(2, true) end function SpriteReader:getInt8() return self:readBytes(1, true) end --[[ * fecha o atributo file --]] function SpriteReader:closeData() return self.file:close() end --[[ * retorna os uma tabela onde table[x][y] representam os respectivos pixels (x, y) --]] function SpriteReader:getPixelsData(id) self:seek(6 + id * 4) self:seek(self:getUint32() + 3) local pixel, pixels = 0, {} local offset = self.posByte + self:getUint16() for x = 1, 32 do pixels[x] = {} for y = 32 , 1, -1 do pixels[x][y] = {255, 0, 255} end end while self.posByte < offset do local tp = self:getUint16() local colored = self:getUint16() pixel = pixel + tp for x = 1, colored do local r,g,b = self:getUint8(), self:getUint8(), self:getUint8() pixels[pixel%32+1][math.floor(pixel/32+1)] = {b, g, r} pixel = pixel + 1 end end --]] return pixels endOs arquivos devem ser colocados juntos em uma pasta, e a pasta deve contem o arquivo Tibia.spr, pode ser outros nomes ou diretorios, porem precisará modificar no script (qualquer noob faz).
Me sinto na obrigação de atribuir crédito a 3 pessoas:Jo3Bingham (pelo tutorial sobre estrutura do spr), Colex (atravès de um script dele pude intender como são organizados os pixels no spr), baxnie (por me ajudar a entender a estrutura do spr, que não obtive total exito atraves do tutorial de Jo3Bingham).
Para usários de Windows aconselho Scite, e para linux gosto de usar o Geany.
Editado Abril 9 por CyberBot