public override async Task SaveObject(string filename) { if (MipMaps == null || !MipMaps.Any()) { return; } ImageEngineFormat format; DomainMipMap mipMap = MipMaps.Where(mm => mm.ImageData != null && mm.ImageData.Length > 0).OrderByDescending(mm => mm.Width > mm.Height ? mm.Width : mm.Height).FirstOrDefault(); if (mipMap == null) { return; } MemoryStream memory = buildDdsImage(MipMaps.IndexOf(mipMap), out format); if (memory == null) { return; } ImageEngineImage ddsImage = new ImageEngineImage(memory); FileStream stream = new FileStream(filename, FileMode.Create); await Task.Run(() => ddsImage.Save(stream, format, MipHandling.KeepTopOnly)); stream.Close(); memory.Close(); }
/// <summary> /// Collects details of current texture, like thumbnail, number of mips, and format. /// </summary> public void EnumerateDetails() { byte[] data = Extract("", true); if (data == null) { DebugOutput.PrintLn("Unable to get image data for: " + FileName); } else { // KFreon: Check formatting etc try { using (ImageEngineImage image = new ImageEngineImage(data)) { NumMips = image.NumMipMaps; Height = image.Height; Width = image.Width; Format = image.Format.InternalFormat.ToString().Replace("DDS_", ""); image.Save(Thumbnail, ImageEngineFormat.JPG, false, 64); } } catch (Exception e) { DebugOutput.PrintLn("Error checking texture: " + e.Message); NumMips = 0; Format = Format ?? Path.GetExtension(FileName); Thumbnail = null; } data = null; } }
/// <summary> /// Saves DdsImage into Data. /// </summary> public void SaveDds(bool onlySaveIfEdited = true) { if (DdsImage == null || (!wasEdited && onlySaveIfEdited)) { return; } try { _loadDdsLock = true; ImageEngineImage newImage = null; using (MemoryStream png = new MemoryStream()) { DdsImage.Save(png); newImage = new ImageEngineImage(png); } Data = newImage.Save(ImageFormat, MipHandling.Default).ToList(); } finally { wasReloaded = true; _loadDdsLock = false; } }
private static Bitmap ImageEngineImageToBitmap(ImageEngineImage image) { // save the image to bmp var bitmapStream = new MemoryStream(); try { image.Save(bitmapStream, new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.PNG), MipHandling.KeepTopOnly, 0, 0, false); } catch (NullReferenceException /* good library */) { image.Save(bitmapStream, new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.PNG), MipHandling.KeepTopOnly); } // load the saved bmp into a new bitmap return(new Bitmap(bitmapStream)); }
private static Bitmap ImageEngineImageToBitmap(ImageEngineImage image) { // save the image to bmp var bitmapStream = new MemoryStream(); image.Save(bitmapStream, new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.BMP), MipHandling.KeepTopOnly); // load the saved bmp into a new bitmap return(new Bitmap(bitmapStream)); }
public void SaveSubImage(SubImage subImage, string path, string extension) { Bitmap bmp = UsefulThings.WinForms.Imaging.CreateBitmap(ImageManager.Instance.image.GetWPFBitmap(), false); UIManager.Instance.MainForm.displayImageBox.Image = bmp; int top = 0, bottom = 0, left = 0, right = 0; foreach (var property in subImage.properties) { if (property.name == "top") { top = Convert.ToInt32(property.value); } if (property.name == "bottom") { bottom = Convert.ToInt32(property.value); } if (property.name == "left") { left = Convert.ToInt32(property.value); } if (property.name == "right") { right = Convert.ToInt32(property.value); } } Rectangle rect = Rectangle.FromLTRB(left, top, right, bottom); if (rect.Width <= 0 || rect.Height <= 0) { LogManager.Instance.MsgError("Invalid sub image on file " + subImage.path); return; } try { bmp = bmp.Clone(rect, bmp.PixelFormat); using (var stream = new MemoryStream()) { bmp.Save(stream, ImageFormat.Png); ImageEngineImage img = new ImageEngineImage(stream.ToArray()); img.Save(path + @"\" + subImage.name + "." + extension, ImageEngineFormat.DDS_DXT3, MipHandling.KeepExisting, 0, 0, false); } } catch (Exception e) { LogManager.Instance.MsgError("Could not save image " + path + @"\" + subImage.name + "." + extension + "\nError: " + e.Message); } }
/// <summary> /// Converts a single .png file to .dds format. /// </summary> /// <param name="file">Full path of the file.</param> /// <param name="inPath">Full input directory path.</param> /// <param name="outPath">Full output directory path.</param> /// <param name="index">Integer label. Start at i = 1.</param> /// <param name="total">Total number of files to be converted.</param> public void ConvertPngToDds(string file, string inPath, string outPath, ref int index, int total) { //get data about file..."D:\\msys2\\home\\Nathan\\dbg\\00004d824c7204b6f7-DDS_ARGB_8.png" string name = Path.GetFileName(file); string[] details = name.Split('-'); if (details.Length > 2) { throw new Exception("Additional details detected."); } if (details.Length == 1) //no details found { details = new string[] { name, "" } } ; ImageFormats.ImageEngineFormatDetails imageDetails; switch (details[1].Split('.')[0]) //A bit of a complicated way to only look at the part without file extension... { case "DDS_ARGB_8": imageDetails = new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.DDS_ARGB_8); break; case "DDS_G16_R16": imageDetails = new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.DDS_G16_R16); break; case "DDS_DXT1": imageDetails = new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.DDS_DXT1); break; case "DDS_DXT5": default: //we don't know what to do here...so we just assume DXT5. imageDetails = new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.DDS_DXT5); break; } //we have already stripped metadata in split. Begin to return it to dds with the stripped metadata. FileStream fs = new FileStream(Path.Combine(outPath, Path.ChangeExtension(details[0], ".dds")), FileMode.Create); ImageEngineImage imi = new ImageEngineImage(Path.Combine(inPath, name)); Console.Out.WriteLine("Converting: " + Path.GetFileName(file) + " " + index + "\\" + total); imi.Save(fs, imageDetails, MipHandling.Default, 0, 0, false); fs.Close(); } }
private void SaveDDS(List <string> paths, string outputPath) { ImageEngineImage outputImage = new ImageEngineImage(paths[0]); for (int i = 1; i < paths.Count; i++) { ImageEngineImage mipImage = new ImageEngineImage(paths[i]); MipMap mip = new MipMap(mipImage.MipMaps[0].Pixels, mipImage.Width, mipImage.Height, mipImage.FormatDetails); outputImage.MipMaps.Add(mip); } ImageFormats.ImageEngineFormatDetails outputFormat = new ImageFormats.ImageEngineFormatDetails(ImageEngineFormat.DDS_DXT1); byte[] data = outputImage.Save(outputFormat, MipHandling.KeepExisting); using (var file = File.Create(outputPath)) { file.Write(data, 0, data.Length); } }
/// <summary> /// Returns current texture as a Bitmap. Option to specify size. /// </summary> /// <param name="pathBIOGame">Path to BIOGame.</param> /// <param name="size">OPTIONAL: Maximum size on any dimension. Defaults to max.</param> /// <returns>Bitmap image of texture.</returns> public Bitmap GetImage(string pathBIOGame, int size = -1) { ITexture2D tex2D = Textures[0]; byte[] imgData = tex2D.GetImageData(); using (ImageEngineImage img = new ImageEngineImage(imgData)) { using (MemoryStream ms = new MemoryStream()) { if (!img.Save(ms, ImageEngineFormat.PNG, MipHandling.KeepTopOnly)) { return(null); } MemoryStream largest = KFreonLib.Textures.Creation.OverlayAndPickDetailed(ms, img.Width, img.Height); return(new Bitmap(largest)); } } }
/// <summary> /// Collects details of current texture, like thumbnail, number of mips, and format. /// </summary> public void EnumerateDetails() { byte[] data = Extract("", true); if (data == null) { DebugOutput.PrintLn("Unable to get image data for: " + FileName); } else { // KFreon: Check formatting etc try { using (ImageEngineImage image = new ImageEngineImage(data)) { NumMips = image.NumMipMaps; Height = image.Height; Width = image.Width; Format = image.Format.InternalFormat; if (OrigWidth == -1) { OrigWidth = Width; } if (OrigHeight == -1) { OrigHeight = Height; } image.Save(Thumbnail, ImageEngineFormat.JPG, MipHandling.Default, 64); } } catch (Exception e) { DebugOutput.PrintLn("Error checking texture: " + e.Message); NumMips = 0; Thumbnail = null; } data = null; } }
public static Bitmap DdsToBmp(int width, int height, byte[] rawData, bool preserveAlpha = true) { ImageEngineImage img = new ImageEngineImage(rawData); var newBytes = img.Save(new ImageEngineFormatDetails(ImageEngineFormat.BMP), MipHandling.Default); Bitmap bmImage = new Bitmap(new MemoryStream(newBytes)); return(bmImage); var pxFormat = PixelFormat.Format32bppRgb; if (preserveAlpha) { pxFormat = PixelFormat.Format32bppArgb; } Bitmap bitmap = new Bitmap(width, height); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pxFormat); IntPtr scan = data.Scan0; int size = bitmap.Width * bitmap.Height * 4; unsafe { byte *p = (byte *)scan; for (int i = 0; i < size; i += 4) { // iterate through bytes. // Bitmap stores it's data in RGBA order. // DDS stores it's data in BGRA order. p[i] = rawData[i + 2]; // blue p[i + 1] = rawData[i + 1]; // green p[i + 2] = rawData[i]; // red p[i + 3] = rawData[i + 3]; // alpha } } bitmap.UnlockBits(data); return(bitmap); }
public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable) { ImageEngineImage image = await Task.Run(() => new ImageEngineImage(filename)); int width = image.Width; int height = image.Height; DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue; DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue; sizeX?.SetPropertyValue(width); sizeY?.SetPropertyValue(height); DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue; mipTailBaseIdx?.SetPropertyValue((int)Math.Log(width > height ? width : height, 2)); DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue; DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue; filePath?.SetPropertyValue(filename); fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss")); DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue; ImageEngineFormat imageFormat = image.Format.InternalFormat; if (!imageFormat.ToString().Contains("DDS")) { throw new Exception($"Image is not in a DDS format. It is actually {imageFormat}."); } if (pfFormat != null) { string formatStr = imageFormat.ToString().Replace("DDS", "PF"); if (formatStr.Contains("ARGB")) { formatStr = "PF_A8R8G8B8"; } else if (formatStr.Contains("G8")) { formatStr = "PF_G8"; } DomainNameTableEntry formatTableEntry = nameTable.SingleOrDefault(nt => nt.Name.String == formatStr) ?? nameTable.AddDomainNameTableEntry(formatStr); pfFormat.SetPropertyValue(formatTableEntry); } MipMaps.Clear(); while (true) { MemoryStream stream = new MemoryStream(); image.Save(stream, imageFormat, MipHandling.KeepTopOnly); await stream.FlushAsync(); MipMaps.Add(new DomainMipMap { ImageData = (await ByteArrayReader.CreateNew(stream.ToArray(), 0x80).Splice()).GetBytes(), // Strip off 128 bytes for the DDS header Width = image.Width, Height = image.Height }); if (width == 1 && height == 1) { break; } if (width > 1) { width /= 2; } if (height > 1) { height /= 2; } if (image.Width > 4 && image.Height > 4) { image.Resize(0.5, false); } } }
/// <summary> /// Collects details of current texture, like thumbnail, number of mips, and format. /// </summary> public void EnumerateDetails() { byte[] data = Extract("", true); if (data == null) DebugOutput.PrintLn("Unable to get image data for: " + FileName); else { // KFreon: Check formatting etc try { using (ImageEngineImage image = new ImageEngineImage(data)) { NumMips = image.NumMipMaps; Height = image.Height; Width = image.Width; Format = image.Format.InternalFormat; if (OrigWidth == -1) OrigWidth = Width; if (OrigHeight == -1) OrigHeight = Height; image.Save(Thumbnail, ImageEngineFormat.JPG, MipHandling.Default, 64); } } catch(Exception e) { DebugOutput.PrintLn("Error checking texture: " + e.Message); NumMips = 0; Thumbnail = null; } data = null; } }
/// <summary> /// Returns current texture as a Bitmap. Option to specify size. /// </summary> /// <param name="pathBIOGame">Path to BIOGame.</param> /// <param name="size">OPTIONAL: Maximum size on any dimension. Defaults to max.</param> /// <returns>Bitmap image of texture.</returns> public Bitmap GetImage(string pathBIOGame, int size = -1) { ITexture2D tex2D = Textures[0]; byte[] imgData = tex2D.GetImageData(); using (ImageEngineImage img = new ImageEngineImage(imgData)) { using (MemoryStream ms = new MemoryStream()) { if (!img.Save(ms, ImageEngineFormat.PNG, MipHandling.KeepTopOnly)) return null; MemoryStream largest = KFreonLib.Textures.Creation.OverlayAndPickDetailed(ms, img.Width, img.Height); return new Bitmap(largest); } } }
/// <summary> /// Collects details of current texture, like thumbnail, number of mips, and format. /// </summary> public void EnumerateDetails() { byte[] data = Extract("", true); if (data == null) DebugOutput.PrintLn("Unable to get image data for: " + FileName); else { // KFreon: Check formatting etc try { using (ImageEngineImage image = new ImageEngineImage(data)) { NumMips = image.NumMipMaps; Height = image.Height; Width = image.Width; Format = image.Format.InternalFormat.ToString().Replace("DDS_", ""); image.Save(Thumbnail, ImageEngineFormat.JPG, false, 64); } } catch(Exception e) { DebugOutput.PrintLn("Error checking texture: " + e.Message); NumMips = 0; Format = Format ?? Path.GetExtension(FileName); Thumbnail = null; } data = null; } }
private bool AutofixInternal(TPFTexInfo tex) { bool retval = false; TPFTexInfo backup = tex.Clone(); string path = tex.Autofixedpath(TemporaryPath); Directory.CreateDirectory(Path.GetDirectoryName(path)); byte[] imgData = tex.Extract(Path.GetDirectoryName(path), true); using (ImageEngineImage img = new ImageEngineImage(imgData)) { var destFormat = tex.ExpectedFormat; img.Resize(UsefulThings.General.RoundToNearestPowerOfTwo(img.Width), false); retval = img.Save(path, destFormat, tex.ExpectedMips > 1 ? MipHandling.Default : MipHandling.KeepTopOnly); } if (!retval) { tex.AutofixSuccess = false; return false; } tex.FilePath = Path.GetDirectoryName(tex.Autofixedpath(TemporaryPath)); tex.FileName = Path.GetFileName(path); // Heff: Cancellation check if (cts.IsCancellationRequested) return false; tex.EnumerateDetails(); // Heff: if fix was successfull, but the number of mips are still wrong, // force it and let texplorer skip the lowest resolutions // Heff: this should no longer happen, but keeping this as it might help in some real odd case. if (tex.ExpectedMips > 1 && (tex.NumMips < tex.ExpectedMips || tex.NumMips < TPFTexInfo.CalculateMipCount(tex.Width, tex.Height))) tex.NumMips = Math.Max(tex.ExpectedMips, TPFTexInfo.CalculateMipCount(tex.Width, tex.Height)); if (!tex.Valid) { tex = backup; tex.AutofixSuccess = false; } else tex.AutofixSuccess = true; return tex.AutofixSuccess; }