private void compressCompositeNormalMap(String originalNormalMapSource, String source, String dest, MaterialDescription matDesc) { Task.WaitAll( saveUncompressed(source, dest, true, FREE_IMAGE_FILTER.FILTER_BILINEAR, new FullImageSizeStrategy(), (resized) => { String fileName = String.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(originalNormalMapSource), resized.Width, Path.GetExtension(originalNormalMapSource)); fileName = Path.Combine(Path.GetDirectoryName(originalNormalMapSource), fileName); if (File.Exists(fileName)) { Log.Info("Using manually supplied resized normal map for {0} size {1}", dest, resized.Width); using (var image = FreeImageBitmap.FromFile(fileName)) { if (image.Width != resized.Width || image.Height != resized.Height) { throw new Exception(String.Format("Image {0} does not match expected size {1}x{1}. Please fix source image.", fileName, resized.Width)); } combineImages(resized, Channel.Alpha, image, Channel.Red, image, Channel.Green, resized, Channel.Blue, resized); } } else { Log.Info("Using automatic resized normal map for {0} size {1}", dest, resized.Width); } }) ); }
public static bool HasDesktopImageFormat(string imagePath) { using (var img = FreeImageBitmap.FromFile(imagePath)) { return(img.Width > img.Height && img.Width > 1900); } }
public void FreeImageFileFile() { using var output = TestFiles.OutputJpg(); using var image = FreeImageBitmap.FromFile(TestFiles.InputJpg); using var resized = new FreeImageBitmap(image, Width, Height); resized.Save(output.Path, FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD); }
/// <summary> /// Compressing Image /// </summary> /// <param name="imagePath">Path to image</param> /// <param name="size">Size to compress</param> /// <returns>Compressing result</returns> public static bool CompressImage(string imagePath, int size) { try { //string newFile = imagePath.Replace(".jpg", ".new"); using (var original = FreeImageBitmap.FromFile(imagePath + ".new")) { int width, height; if (original.Width > original.Height) { width = size; height = original.Height * size / original.Width; } else { width = original.Width * size / original.Height; height = size; } var resized = new FreeImageBitmap(original, width, height); // JPEG_QUALITYGOOD is 75 JPEG. // JPEG_BASELINE strips metadata (EXIF, etc.) resized.Save(imagePath + ".jpg", FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); } System.IO.File.Delete(imagePath + ".new"); return(true); } catch (Exception ex) { return(false); } }
public static byte[] ImageToByteArray(string path, FREE_IMAGE_FORMAT format) { using (var image = FreeImageBitmap.FromFile(path)) { using (var m = new MemoryStream()) { image.Save(m, format); return(m.ToArray()); } } }
public static byte[] ThumbNailByteArray(string path, FREE_IMAGE_FORMAT format) { using (var image = FreeImageBitmap.FromFile(path)) { var newImage = image.GetThumbnailImage(1000, true); using (var m = new MemoryStream()) { newImage.Save(m, format); return(m.ToArray()); } } }
internal static void FreeImageResize(string path, int size, string outputDirectory) { using (var original = FreeImageBitmap.FromFile(path)) { var scaled = ScaledSize(original.Width, original.Height, size); var resized = new FreeImageBitmap(original, scaled.width, scaled.height); // JPEG_QUALITYGOOD is 75 JPEG. // JPEG_BASELINE strips metadata (EXIF, etc.) resized.Save(OutputPath(path, outputDirectory, FreeImage), FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); } }
public void FreeImageResize(string input) { using (var original = FreeImageBitmap.FromFile(input)) { var scaled = ScaledSize(original.Width, original.Height, ThumbnailSize); var resized = new FreeImageBitmap(original, scaled.width, scaled.height); // JPEG_QUALITYGOOD is 75 JPEG. // JPEG_BASELINE strips metadata (EXIF, etc.) resized.Save(OutputPath(input, FreeImage), FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); } }
private void combineSingleChannelMaps(String redSource, Channel redSourceChannel, String greenSource, Channel greenSourceChannel, String tempFile, String destinationFile, MaterialDescription matDesc, Action <String, String, MaterialDescription> compressFunction) { Log.Info("Building composite image with red source {0} and green source {1}", redSource, greenSource); using (FreeImageBitmap redMap = FreeImageBitmap.FromFile(redSource)) { using (FreeImageBitmap greenMap = FreeImageBitmap.FromFile(greenSource)) { using (FreeImageBitmap combined = createImageFromChannels(redMap, redSourceChannel, greenMap, greenSourceChannel)) { saveImage(combined, tempFile, TempFileImageFormat); compressFunction(tempFile, destinationFile, matDesc); deleteFile(tempFile); } } } }
private void addMapToBlueAndCompress(String rgSource, String bSource, Channel bSourceChannel, String tempFile, String destinationFile, MaterialDescription matDesc, Action <String, String, MaterialDescription> compressFunction) { Log.Info("Building composite image with RG {0} and B {1}", rgSource, bSource); using (FreeImageBitmap rgMap = FreeImageBitmap.FromFile(rgSource)) { using (FreeImageBitmap bMap = FreeImageBitmap.FromFile(bSource)) { using (FreeImageBitmap combined = createImageFromChannels(rgMap, Channel.Red, rgMap, Channel.Green, bMap, bSourceChannel)) { saveImage(combined, tempFile, TempFileImageFormat); compressFunction(tempFile, destinationFile, matDesc); deleteFile(tempFile); } } } }
private void addMapToAlphaAndCompress(String rgbSource, String alphaSource, Channel alphaSourceChannel, String tempFile, String destinationFile, MaterialDescription matDesc, Action <String, String, MaterialDescription> compressFunction) { Log.Info("Building composite image with RGB {0} and alpha {1}", rgbSource, alphaSource); using (FreeImageBitmap rgbMap = FreeImageBitmap.FromFile(rgbSource)) { using (FreeImageBitmap alphaMap = FreeImageBitmap.FromFile(alphaSource)) { using (FreeImageBitmap combined = createImageFromChannels(alphaMap, alphaSourceChannel, rgbMap)) { saveImage(combined, tempFile, TempFileImageFormat); compressFunction(tempFile, destinationFile, matDesc); deleteFile(tempFile); } } } }
//private unsafe byte getColor(int x, int y, FreeImageBitmap src, Channel channel) //{ // int bpp = 4; // if (src.PixelFormat == FreeImageAPI.PixelFormat.Format24bppRgb) // { // bpp = 3; // } // byte* pixel = (byte*)src.Bits.ToPointer(); // pixel += (src.Pitch * (src.Height - y - 1) + x) * bpp; // switch (channel) // { // case Channel.Alpha: // return pixel[3]; // case Channel.Red: // return pixel[2]; // case Channel.Green: // return pixel[1]; // case Channel.Blue: // return pixel[0]; // } // throw new NotSupportedException(); //Won't get here //} private async Task saveUncompressed(String sourceFile, String destFile, bool lossless, FREE_IMAGE_FILTER filter, ImagePageSizeStrategy pageSizeStrategy, Action <FreeImageBitmap> afterResize = null) { await Task.Run(() => { if ((outputFormats & OutputFormats.Uncompressed) != 0) { Log.Info("Creating paged data for {0}", sourceFile); using (FreeImageBitmap source = FreeImageBitmap.FromFile(sourceFile)) { using (var stream = File.Open(String.Format(PagedTextureNameFormat, destFile), FileMode.Create, FileAccess.ReadWrite)) { PagedImage.fromBitmap(source, 128, 1, stream, PagedImage.ImageType.WEBP, maxSize, lossless, filter, pageSizeStrategy, afterResize); } } } }); }
internal static void FreeImageResize(string path, int size, string outputDirectory) { using (var original = FreeImageBitmap.FromFile(path)) { int width, height; if (original.Width > original.Height) { width = size; height = original.Height * size / original.Width; } else { width = original.Width * size / original.Height; height = size; } var resized = new FreeImageBitmap(original, width, height); // JPEG_QUALITYGOOD is 75 JPEG. // JPEG_BASELINE strips metadata (EXIF, etc.) resized.Save(OutputPath(path, outputDirectory, FreeImage), FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); } }
private void writeSimpleDiffuseSprite(MaterialDescription description, MaterialRepository repo) { String diffuseSrc = getSourceFullPath(description.DiffuseMapName); if (!imageNeedsCompression(diffuseSrc)) { return; } String diffuseDest = getDestBasePath(description.DiffuseMapName); String normalDest = getDestBasePath(description.NormalMapName); String normalTmp = getTempPath(description.NormalMapName); using (FreeImageBitmap diffuseMap = FreeImageBitmap.FromFile(diffuseSrc)) { using (FreeImageBitmap normalMap = new FreeImageBitmap(diffuseMap.Width, diffuseMap.Height, FreeImageAPI.PixelFormat.Format32bppArgb)) { normalMap.FillBackground(new RGBQUAD(new FreeImageAPI.Color() { R = 0x80, G = 0x80, B = 0, A = 255 })); using (FreeImageBitmap combined = createImageFromChannels(normalMap, Channel.Red, normalMap, Channel.Green, diffuseMap, Channel.Alpha)) { saveImage(combined, normalTmp, TempFileImageFormat); compressCompositeNormalMap(diffuseSrc, normalTmp, normalDest, description); deleteFile(normalTmp); } } } Log.Info("Compressing diffuse map {0} directly", description.DiffuseMapName); compressDiffuseMap(diffuseSrc, diffuseDest, description); }
public static void Thumbnail(string path, string outpath) { const int size = 150; using (var original = FreeImageBitmap.FromFile(path)) { int width, height; if (original.Width > original.Height) { width = size; height = original.Height * size / original.Width; } else { width = original.Width * size / original.Height; height = size; } var resized = new FreeImageBitmap(original, width, height); // JPEG_QUALITYGOOD is 75 JPEG. // JPEG_BASELINE strips metadata (EXIF, etc.) //resized.Save() resized.Save(outpath); } }
public new IFileInfo GetFileInfo(string subpath) { var fileInfo = base.GetFileInfo(subpath); if (fileInfo.Exists) { return(fileInfo); } var matchResult = _options.IsMatch(subpath, _options.PathMatch); if (!matchResult.Result) { return(fileInfo); } var imageHandleDto = matchResult.Data; //生成文件 fileInfo = base.GetFileInfo($"{imageHandleDto.ImagePath}{imageHandleDto.ImageName}.{imageHandleDto.ImageExtensions}"); if (!fileInfo.Exists) { return(fileInfo); } var newImagePath = Path.Join(Root.Replace("\\", "/"), subpath).Replace("//", "/"); //_stopwatch.Start(); //var settings = new ProcessImageSettings() //{ // Width = imageHandleDto.ImageWidth, // Height = imageHandleDto.ImageHeight, // ResizeMode = CropScaleMode.Max, // SaveFormat = FileFormat.Jpeg, // JpegQuality = 75, // JpegSubsampleMode = ChromaSubsampleMode.Subsample420 //}; //using (var output = new FileStream(newImagePath, FileMode.Create)) //{ // MagicImageProcessor.ProcessImage(fileInfo.PhysicalPath, output, settings); //} //_stopwatch.Stop(); //_logger.LogDebug($"Magick.NET耗时{_stopwatch.ElapsedMilliseconds}ms"); //File.Delete(newImagePath); //_stopwatch.Restart(); //using (var original = FreeImageBitmap.FromFile(fileInfo.PhysicalPath)) //{ // using (var resized = new FreeImageBitmap(original, imageHandleDto.ImageWidth, imageHandleDto.ImageHeight)) // { // resized.Save(newImagePath, FREE_IMAGE_FORMAT.FIF_JPEG, // FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | // FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); // } //} //_stopwatch.Stop(); //_logger.LogDebug($"FreeImage FromFilePath耗时{_stopwatch.ElapsedMilliseconds}ms"); //File.Delete(newImagePath); //_stopwatch.Restart(); //using (var original = FreeImageBitmap.FromStream(fileInfo.CreateReadStream())) //{ // using (var resized = new FreeImageBitmap(original, imageHandleDto.ImageWidth, imageHandleDto.ImageHeight)) // { // resized.Save(newImagePath, FREE_IMAGE_FORMAT.FIF_JPEG, // FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | // FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); // } //} //_stopwatch.Stop(); //_logger.LogDebug($"FreeImage FromFileStream耗时{_stopwatch.ElapsedMilliseconds}ms"); _stopwatch.Start(); FREE_IMAGE_FORMAT imageFormat = 0; switch (imageHandleDto.ImageExtensions.ToLower()) { case "jpg": case "jpeg": imageFormat = FREE_IMAGE_FORMAT.FIF_JPEG; break; case "png": imageFormat = FREE_IMAGE_FORMAT.FIF_PNG; break; case "gif": imageFormat = FREE_IMAGE_FORMAT.FIF_GIF; break; case "ico": imageFormat = FREE_IMAGE_FORMAT.FIF_ICO; break; default: imageFormat = FREE_IMAGE_FORMAT.FIF_UNKNOWN; break; } using (var original = FreeImageBitmap.FromFile(fileInfo.PhysicalPath)) { var size = original.Width / (double)imageHandleDto.ImageWidth; if ((imageHandleDto.ImageHeight * size) > original.Height) { size = original.Height / (double)imageHandleDto.ImageHeight; } var width = original.Width / size; var height = original.Height / size; width = width > original.Width ? original.Width : width; height = height > original.Height ? original.Height : height; using (var resized = original.GetScaledInstance((int)width, (int)height, FREE_IMAGE_FILTER.FILTER_BICUBIC)) { double left, top, right, bottom; var halfWidth = Math.Floor(Convert.ToDouble(imageHandleDto.ImageWidth / 2)); var halfHeight = Math.Floor(Convert.ToDouble(imageHandleDto.ImageHeight / 2)); var centerX = Math.Round(width / 2); var centerY = Math.Round(height / 2); if (resized.Width > imageHandleDto.ImageWidth) { left = centerX - halfWidth; right = centerX + halfWidth; } else { left = 0; right = resized.Width; } if (resized.Height > imageHandleDto.ImageHeight) { bottom = centerY - halfHeight; top = centerY + halfHeight; } else { bottom = 0; top = resized.Height; } using (var crop = resized.Copy((int)left, (int)top, (int)right, (int)bottom)) { //, FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE crop.Save(newImagePath, imageFormat, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } } } _stopwatch.Stop(); _logger.LogDebug($"FreeImage FromFilePath耗时{_stopwatch.ElapsedMilliseconds}ms"); fileInfo = base.GetFileInfo(subpath); return(fileInfo); }
public new IFileInfo GetFileInfo(string subpath) { var fileInfo = base.GetFileInfo(subpath); if (fileInfo.Exists) { return(fileInfo); } var matchResult = _options.IsMatch(subpath, _options.PathMatch); if (!matchResult.Result) { return(fileInfo); } var imageHandleDto = matchResult.Data; //生成文件 fileInfo = base.GetFileInfo($"{imageHandleDto.ImagePath}{imageHandleDto.ImageName}.{imageHandleDto.ImageExtensions}"); if (!fileInfo.Exists) { return(fileInfo); } var newImagePath = Path.Join(Root.Replace("\\", "/"), subpath).Replace("//", "/"); //_stopwatch.Start(); //var settings = new ProcessImageSettings() //{ // Width = imageHandleDto.ImageWidth, // Height = imageHandleDto.ImageHeight, // ResizeMode = CropScaleMode.Max, // SaveFormat = FileFormat.Jpeg, // JpegQuality = 75, // JpegSubsampleMode = ChromaSubsampleMode.Subsample420 //}; //using (var output = new FileStream(newImagePath, FileMode.Create)) //{ // MagicImageProcessor.ProcessImage(fileInfo.PhysicalPath, output, settings); //} //_stopwatch.Stop(); //_logger.LogDebug($"Magick.NET耗时{_stopwatch.ElapsedMilliseconds}ms"); //File.Delete(newImagePath); //_stopwatch.Restart(); //using (var original = FreeImageBitmap.FromFile(fileInfo.PhysicalPath)) //{ // using (var resized = new FreeImageBitmap(original, imageHandleDto.ImageWidth, imageHandleDto.ImageHeight)) // { // resized.Save(newImagePath, FREE_IMAGE_FORMAT.FIF_JPEG, // FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | // FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); // } //} //_stopwatch.Stop(); //_logger.LogDebug($"FreeImage FromFilePath耗时{_stopwatch.ElapsedMilliseconds}ms"); //File.Delete(newImagePath); //_stopwatch.Restart(); //using (var original = FreeImageBitmap.FromStream(fileInfo.CreateReadStream())) //{ // using (var resized = new FreeImageBitmap(original, imageHandleDto.ImageWidth, imageHandleDto.ImageHeight)) // { // resized.Save(newImagePath, FREE_IMAGE_FORMAT.FIF_JPEG, // FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | // FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE); // } //} //_stopwatch.Stop(); //_logger.LogDebug($"FreeImage FromFileStream耗时{_stopwatch.ElapsedMilliseconds}ms"); _stopwatch.Start(); FREE_IMAGE_FORMAT imageFormat = 0; switch (imageHandleDto.ImageExtensions.ToLower()) { case "jpg": case "jpeg": imageFormat = FREE_IMAGE_FORMAT.FIF_JPEG; break; case "png": imageFormat = FREE_IMAGE_FORMAT.FIF_PNG; break; case "gif": imageFormat = FREE_IMAGE_FORMAT.FIF_GIF; break; case "ico": imageFormat = FREE_IMAGE_FORMAT.FIF_ICO; break; default: imageFormat = FREE_IMAGE_FORMAT.FIF_UNKNOWN; break; } using (var original = FreeImageBitmap.FromFile(fileInfo.PhysicalPath)) { int x = 0; int y = 0; int width = original.Width; int height = original.Height; if ((double)original.Width / (double)original.Height > (double)imageHandleDto.ImageWidth / (double)imageHandleDto.ImageHeight) { height = original.Height; width = original.Height * imageHandleDto.ImageWidth / imageHandleDto.ImageHeight; y = 0; x = (original.Width - width) / 2; } else { width = original.Width; height = original.Width * imageHandleDto.ImageHeight / imageHandleDto.ImageWidth; x = 0; y = (original.Height - height) / 2; } int left = x, top = y + height, right = x + width, bottom = y; using (var crop = original.Copy(left, top, right, bottom)) { using (var resized = crop.GetScaledInstance(imageHandleDto.ImageWidth, imageHandleDto.ImageHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC)) { //, FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD | FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE resized.Save(newImagePath, imageFormat, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } } } _stopwatch.Stop(); _logger.LogDebug($"FreeImage FromFilePath耗时{_stopwatch.ElapsedMilliseconds}ms"); fileInfo = base.GetFileInfo(subpath); return(fileInfo); }
/// <summary> /// Compile input images into WAD texture file. /// </summary> /// <param name="outputFilename">Output wad file path.</param> /// <param name="images">Input image files.</param> /// <param name="names">Names of textures.</param> /// <param name="reserverLastPalColor">Reserve last color in palette if name starts with {.</param> public static void CreateWad(string outputFilename, string[] images, string[] names, bool reserverLastPalColor = false) { using (FileStream fs = new FileStream(outputFilename, FileMode.Create)) using (BinaryWriter bw = new BinaryWriter(fs)) { //Convert bitmaps to 8bpp format List <FreeImageBitmap> imgs = new List <FreeImageBitmap>(); for (int i = 0; i < images.Length; i++) { string image = images[i]; //Quantize images FreeImageBitmap originalImage = FreeImageBitmap.FromFile(image); //If texture will be transparent, reserve last color if enabled bool reserveLastClr = (names[i].StartsWith("{") && reserverLastPalColor); int r = reserveLastClr ? 1 : 0; originalImage.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors - r); originalImage.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP); if (reserveLastClr) { originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(Color.Blue); } //TODO: Transparent png, originalImage.SwapColors(, Color.Blue, true); imgs.Add(originalImage); } uint[] offsets = new uint[images.Length]; uint[] sizes = new uint[images.Length]; //WAD header bw.Write(WadHeaderId); bw.Write(images.Length); bw.Write(0); //This will be changed later //Write textures for (int i = 0; i < images.Length; i++) { uint posTextureStart = (uint)bw.BaseStream.Position; offsets[i] = posTextureStart; //Texture name byte[] name = CreateTextureName(names[i]); bw.Write(name, 0, name.Length); //Texture dimensions bw.Write(imgs[i].Width); bw.Write(imgs[i].Height); //Offsets uint posImage = (uint)(bw.BaseStream.Position - posTextureStart); bw.Write(posImage + 16); //image int pixelSize = ((imgs[i].Width) * (imgs[i].Height)); int m1 = ((imgs[i].Width / 2) * (imgs[i].Height / 2)); int m2 = ((imgs[i].Width / 4) * (imgs[i].Height / 4)); int m3 = ((imgs[i].Width / 8) * (imgs[i].Height / 8)); bw.Write((uint)(posImage + pixelSize + 16)); //mipmap1 bw.Write((uint)(posImage + pixelSize + m1 + 16)); //mipmap2 bw.Write((uint)(posImage + pixelSize + m1 + m2 + 16)); //mipmap3 //Write pixel data imgs[i].RotateFlip(RotateFlipType.RotateNoneFlipX); byte[] arr = new byte[imgs[i].Width * imgs[i].Height]; System.Runtime.InteropServices.Marshal.Copy(imgs[i].GetScanlinePointer(0), arr, 0, arr.Length); Array.Reverse(arr); bw.Write(arr); // //Mip map data int factor = 2; for (int a = 0; a < 3; a++) { int widthMM = (imgs[i].Width / factor); int heightMM = (imgs[i].Height / factor); using (FreeImageBitmap clBmp = imgs[i].GetScaledInstance(widthMM, heightMM, FREE_IMAGE_FILTER.FILTER_LANCZOS3)) { //TODO: opravit png, priesvitnost clBmp.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors, imgs[i].Palette); byte[] arrMM = new byte[widthMM * heightMM]; System.Runtime.InteropServices.Marshal.Copy(clBmp.GetScanlinePointer(0), arrMM, 0, arrMM.Length); Array.Reverse(arrMM); bw.Write(arrMM); } factor *= 2; } //Unknown 2 bytes bw.Write(new byte[] { 0x00, 0x01 }); //Write color palette for (int p = 0; p < imgs[i].Palette.Length; p++) { bw.Write(imgs[i].Palette[p].rgbRed); bw.Write(imgs[i].Palette[p].rgbGreen); bw.Write(imgs[i].Palette[p].rgbBlue); } //Padding bw.Write(new byte[] { 0x00, 0x00 }); sizes[i] = (uint)bw.BaseStream.Position - posTextureStart; } long posLumps = bw.BaseStream.Position; bw.Seek(8, SeekOrigin.Begin); bw.Write((uint)posLumps); bw.Seek((int)posLumps, SeekOrigin.Begin); //Write Lumps infos for (int i = 0; i < images.Length; i++) { bw.Write(offsets[i]); bw.Write(sizes[i]); bw.Write(sizes[i]); bw.Write((byte)0x43); bw.Write((byte)0); bw.Write(new byte[] { 0x00, 0x00 }); byte[] name = CreateTextureName(names[i]); bw.Write(name, 0, name.Length); } //Free resources for (int i = 0; i < imgs.Count; i++) { imgs[i].Dispose(); } } }