public override void Export(Asset asset, string path) { Texture texture = (asset as Texture); TDX tdx = (texture.SupportingDocuments["Source"] as TDX); Stopwatch sw = new Stopwatch(); sw.Start(); if (tdx == null) { SceneManager.Current.UpdateProgress($"Saving {texture.Name}"); tdx = TDX.LoadFromBitmap(texture.SupportingDocuments["Source"] as Bitmap, texture.Name, settings.GetSetting <D3DFormat>("Format")); tdx.SetFlags(TDX.Flags.sRGB); } //tdx.Save(Path.Combine(path, $"{texture.Name}.tdx")); tdx.Save(path); sw.Stop(); Console.WriteLine(sw.Elapsed); SceneManager.Current.UpdateProgress($"{texture.Name}.tdx saved!"); }
public void SaveTexture(VTMapEntry textureEntry, string outputPath, bool SaveTDX, bool SaveTGA, bool SaveOther, ImageFormat format) { int divisor = GetDivisor(); int xPos = PageNum == 0 ? textureEntry.Column : textureEntry.Column / divisor; int yPos = PageNum == 0 ? textureEntry.Row : textureEntry.Row / divisor; int tileRow = (int)Math.Floor(yPos / (float)TileSize); int tileCol = (int)Math.Floor(xPos / (float)TileSize); tileRow = tileRow < 0 ? 0 : tileRow; tileCol = tileCol < 0 ? 0 : tileCol; int numTilesX = (int)Math.Ceiling(textureEntry.GetWidth(PageNum) / (float)TileSize); int numTilesY = (int)Math.Ceiling(textureEntry.GetHeight(PageNum) / (float)TileSize); int bitmapheight = textureEntry.GetHeight(PageNum); int bitmapwidth = textureEntry.GetWidth(PageNum); Bitmap stitched = new Bitmap(bitmapwidth, bitmapheight); D3DFormat guessedFormat = D3DFormat.DXT5; bool formatGuessed = false; for (int row = tileRow; row < Tiles.Count && row <= tileRow + numTilesY; row++) { int rowStart = row * TileSize; int rowEnd = (row + 1) * TileSize; for (int col = tileCol; col < Tiles[row].Count && col <= tileCol + numTilesX; col++) { if (Tiles[row][col] == null) { continue; } int colStart = col * TileSize; int colEnd = (col + 1) * TileSize; if (Tiles[row][col].Texture == null) { Tiles[row][col].GetTextureFromZAD(); } if (Tiles[row][col].Texture == null) { continue; } if (!formatGuessed) { guessedFormat = Tiles[row][col].Texture.Format; } Bitmap decompressed = Tiles[row][col].Texture.GetBitmap(); int firstPixelRow = rowStart < yPos ? yPos - rowStart : TilePadding; int lastPixelRow = TileSize + TilePadding; int firstPixelCol = colStart < xPos ? xPos - colStart : TilePadding; int lastPixelCol = TileSize + TilePadding; for (int y = firstPixelRow; y < lastPixelRow; y++) { if ((row * TileSize + (y - TilePadding)) - (yPos) >= bitmapheight) { break; } for (int x = firstPixelCol; x < lastPixelCol; x++) { if ((col * TileSize + (x - TilePadding)) - xPos >= bitmapwidth) { break; } Color pixelColour = decompressed.GetPixel(x, y); stitched.SetPixel((col * TileSize + (x - TilePadding)) - xPos, (row * TileSize + (y - TilePadding)) - (yPos), pixelColour); } } } } if (!Directory.Exists(Path.GetDirectoryName(outputPath))) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); } if (SaveTDX) { TDX newtdx = TDX.LoadFromBitmap(stitched, Path.GetFileNameWithoutExtension(outputPath), guessedFormat); newtdx.Save(outputPath); } if (SaveTGA) { if (File.Exists(outputPath)) { File.Delete(outputPath); } using (FileStream stream = new FileStream(outputPath, FileMode.OpenOrCreate)) using (BinaryWriter writer = new BinaryWriter(stream)) { int tgaWidth = bitmapwidth; int tgaHeight = bitmapheight; int tgaTileRowCount = Tiles.Count - 1; writer.Write((byte)0); writer.Write((byte)0); writer.Write((byte)2); writer.Write((short)0); writer.Write((short)0); writer.Write((byte)0); writer.Write((short)0); writer.Write((short)0); writer.Write((short)bitmapwidth); writer.Write((short)bitmapheight); writer.Write((byte)32); writer.Write((byte)0); BitmapData data = stitched.LockBits(new Rectangle(0, 0, stitched.Width, stitched.Height), ImageLockMode.ReadOnly, stitched.PixelFormat); unsafe { // important to use the BitmapData object's Width and Height // properties instead of the Bitmap's. for (int x = data.Height - 1; x >= 0; x--) { byte *row = (byte *)data.Scan0 + (x * data.Stride); for (int y = 0; y < data.Width; y++) { int columnOffset = y * 4; byte B = row[columnOffset]; byte G = row[columnOffset + 1]; byte R = row[columnOffset + 2]; byte alpha = row[columnOffset + 3]; writer.Write(B); writer.Write(G); writer.Write(R); writer.Write(alpha); } } } stitched.UnlockBits(data); } } if (SaveOther) { using (FileStream str = File.OpenWrite(outputPath)) { stitched.Save(str, format); } } stitched.Dispose(); }