public void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention) { var rawResList = psb.CollectResources <AudioMetadata>(); if (order == PsbLinkOrderBy.Order) { for (int i = 0; i < rawResList.Count; i++) { var resMd = rawResList[i]; var fullPath = Path.Combine(baseDir ?? "", resPaths[i]); resMd.Link(fullPath, context); } return; } foreach (var resPath in resPaths) { var resMd = rawResList.FirstOrDefault(r => r.Name == Path.GetFileNameWithoutExtension(resPath)); if (resMd == null) { Console.WriteLine($"[WARN] {resPath} is not used."); continue; } var fullPath = Path.Combine(baseDir ?? "", resPath); resMd.Link(fullPath, context); } }
/// <summary> /// Convert a PSB to External Texture PSB. /// </summary> /// <param name="inputPath"></param> /// <param name="order"></param> /// <param name="format"></param> public static void UnlinkToFile(string inputPath, PsbLinkOrderBy order = PsbLinkOrderBy.Name, PsbImageFormat format = PsbImageFormat.Png) { if (!File.Exists(inputPath)) { return; } var name = Path.GetFileNameWithoutExtension(inputPath); var dirPath = Path.Combine(Path.GetDirectoryName(inputPath), name); if (File.Exists(dirPath)) { name += "-resources"; dirPath += "-resources"; } if (!Directory.Exists(dirPath)) //ensure there is no file with same name! { Directory.CreateDirectory(dirPath); } var psb = new PSB(inputPath); var texs = psb.Unlink(); var texExt = format == PsbImageFormat.Bmp ? ".bmp" :".png"; var texFormat = format == PsbImageFormat.Bmp ? ImageFormat.Bmp : ImageFormat.Png; switch (order) { case PsbLinkOrderBy.Convention: foreach (var tex in texs) { tex.Save(Path.Combine(dirPath, tex.Tag + texExt), texFormat); } break; case PsbLinkOrderBy.Name: foreach (var tex in texs) { tex.Save(Path.Combine(dirPath, $"{name}_{tex.Tag}{texExt}"), texFormat); } break; case PsbLinkOrderBy.Order: for (var i = 0; i < texs.Count; i++) { var tex = texs[i]; tex.Save(Path.Combine(dirPath, $"{i}{texExt}"), texFormat); } break; } }
/// <summary> /// Link Textures /// </summary> /// <param name="psb"></param> /// <param name="resPaths">resource paths</param> /// <param name="baseDir"></param> /// <param name="order">how to arrange images</param> /// <param name="isExternal">Whether this is an external texture PSB</param> public static void Link(this PSB psb, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention, bool isExternal = false) { var context = FreeMount.CreateContext(); if (psb.Type == PsbType.Motion) { PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order, isExternal); return; } if (psb.TypeHandler != null) { psb.TypeHandler.Link(psb, context, resPaths, baseDir, order); } else { PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order); } }
/// <summary> /// Inlined PSB -> External Texture PSB. Inverse of Link /// </summary> /// <param name="psb"></param> /// <param name="order">To make a regular external texture PSB you should set it to <see cref="PsbLinkOrderBy.Name"/>.</param> /// <param name="disposeResInPsb">Whether to remove resources in PSB. To make a real external texture PSB you should set it to true.</param> /// <returns>Ordered textures</returns> public static List <Bitmap> UnlinkImages(PSB psb, PsbLinkOrderBy order = PsbLinkOrderBy.Name, bool disposeResInPsb = true) { var resources = psb.CollectResources <ImageMetadata>(); List <Bitmap> texs = new List <Bitmap>(); for (int i = 0; i < resources.Count; i++) { var resource = resources[i]; var tex = RL.ConvertToImage(resource.Data, resource.PalData, resource.Height, resource.Width, resource.PixelFormat, resource.PalettePixelFormat); switch (order) { case PsbLinkOrderBy.Convention: tex.Tag = resource.GetFriendlyName(psb.Type); break; default: var tId = resource.TextureIndex; if (tId == null) { throw new FormatException( "Unable to unlink with texture names since they can't be recognized."); } tex.Tag = $"tex{tId.Value:D3}"; break; } texs.Add(tex); //Finally, dispose if (disposeResInPsb) { resource.Data = null; } } return(texs); }
public static void UnlinkImagesToFile(PSB psb, FreeMountContext context, string name, string dirPath, bool disposeResInPsb = true, PsbLinkOrderBy order = PsbLinkOrderBy.Name) { var texs = UnlinkImages(psb, order, disposeResInPsb); var texExt = context.ImageFormat.DefaultExtension(); var texFormat = context.ImageFormat.ToImageFormat(); switch (order) { case PsbLinkOrderBy.Convention: foreach (var tex in texs) { tex.Save(Path.Combine(dirPath, tex.Tag + texExt), texFormat); } break; case PsbLinkOrderBy.Name: foreach (var tex in texs) { tex.Save(Path.Combine(dirPath, $"{name}_{tex.Tag}{texExt}"), texFormat); } break; case PsbLinkOrderBy.Order: for (var i = 0; i < texs.Count; i++) { var tex = texs[i]; tex.Save(Path.Combine(dirPath, $"{i}{texExt}"), texFormat); } break; } return; }
private static void Link(string psbPath, List <string> texPaths, PsbLinkOrderBy order) { if (!File.Exists(psbPath)) { return; } var name = Path.GetFileNameWithoutExtension(psbPath); var ext = Path.GetExtension(psbPath); try { List <string> texs = new List <string>(); foreach (var texPath in texPaths) { if (File.Exists(texPath)) { texs.Add(texPath); } else if (Directory.Exists(texPath)) { texs.AddRange(Directory.EnumerateFiles(texPath)); } } PSB psb = new PSB(psbPath); psb.Link(texs, order: order, isExternal: true); psb.Merge(); File.WriteAllBytes(Path.ChangeExtension(psbPath, "linked" + ext), psb.Build()); } catch (Exception e) { Console.WriteLine(e); } Console.WriteLine($"Link {name} succeed."); }
public static void LinkImages(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention, bool isExternal = false) { if (isExternal) { MotionType.MotionResourceInstrument(psb); } var rawResList = psb.CollectResources <ImageMetadata>(); if (order == PsbLinkOrderBy.Order) { for (int i = 0; i < rawResList.Count; i++) { var resMd = rawResList[i]; var fullPath = Path.Combine(baseDir ?? "", resPaths[i]); resMd.Link(fullPath, context); } return; } var resList = rawResList.ToList(); if (order == PsbLinkOrderBy.Name) { if (psb.Platform == PsbSpec.krkr) { throw new InvalidOperationException( $"Can not link by file name for krkr PSB. Please consider using {PsbLinkOrderBy.Convention}"); } resList.Sort((md1, md2) => (int)(((ImageMetadata)md1).TextureIndex ?? 0) - (int)(((ImageMetadata)md2).TextureIndex ?? 0)); } for (var i = 0; i < resPaths.Count; i++) { var resPath = resPaths[i]; var resName = Path.GetFileNameWithoutExtension(resPath); //var resMd = uint.TryParse(resName, out uint rid) // ? resList.FirstOrDefault(r => r.Index == rid) // : resList.FirstOrDefault(r => // resName == $"{r.Part}{PsbResCollector.ResourceNameDelimiter}{r.Name}"); //Scan for Resource ImageMetadata resMd = null; if (order == PsbLinkOrderBy.Name) { if (resName == null) { continue; } if (resList.Count == 1 && resPaths.Count == 1) { //If there is only one resource and one texture, we won't care about file name. resMd = resList[0]; } else { var texIdx = ImageMetadata.GetTextureIndex(resName); if (texIdx == null) { Console.WriteLine($"[WARN]{resPath} is not used since the file name cannot be recognized."); continue; } if (resList.Count <= texIdx.Value) { Console.WriteLine($"[WARN]{resPath} is not used since the tex No. is too large."); continue; } resMd = resList[(int)texIdx.Value]; } } else //if (order == PsbLinkOrderBy.Convention) { resMd = resList.FirstOrDefault(r => resName == $"{r.Part}{Consts.ResourceNameDelimiter}{r.Name}"); if (resMd == null && uint.TryParse(resName, out uint rid)) { //This Link has no support for raw palette resMd = resList.FirstOrDefault(r => r.Index == rid); } if (resMd == null && psb.Type == PsbType.Pimg) { resMd = resList.FirstOrDefault(r => resName == Path.GetFileNameWithoutExtension(r.Name)); } } if (resMd == null) { Console.WriteLine($"[WARN]{resPath} is not used."); continue; } var fullPath = Path.Combine(baseDir ?? "", resPath.Replace('/', '\\')); resMd.Link(fullPath, context); } }
public virtual void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention) { PsbResHelper.LinkImages(psb, context, resPaths, baseDir, order); }
public virtual void UnlinkToFile(PSB psb, FreeMountContext context, string name, string dirPath, bool outputUnlinkedPsb = true, PsbLinkOrderBy order = PsbLinkOrderBy.Name) { PsbResHelper.UnlinkImagesToFile(psb, context, name, dirPath, outputUnlinkedPsb, order); }
public virtual List <Bitmap> Unlink(PSB psb, PsbLinkOrderBy order = PsbLinkOrderBy.Name, bool disposeResInPsb = true) { return(PsbResHelper.UnlinkImages(psb, order, disposeResInPsb)); }
/// <summary> /// Convert a PSB to External Texture PSB. /// </summary> /// <param name="inputPath"></param> /// <param name="outputUnlinkedPsb">output unlinked PSB; otherwise only output textures</param> /// <param name="order"></param> /// <param name="format"></param> /// <returns>The unlinked PSB path</returns> public static string UnlinkToFile(string inputPath, bool outputUnlinkedPsb = true, PsbLinkOrderBy order = PsbLinkOrderBy.Name, PsbImageFormat format = PsbImageFormat.png) { if (!File.Exists(inputPath)) { return(null); } var name = Path.GetFileNameWithoutExtension(inputPath); var dirPath = Path.Combine(Path.GetDirectoryName(inputPath), name); var psbSavePath = inputPath; if (File.Exists(dirPath)) { name += "-resources"; dirPath += "-resources"; } if (!Directory.Exists(dirPath)) //ensure there is no file with same name! { Directory.CreateDirectory(dirPath); } var context = FreeMount.CreateContext(); context.ImageFormat = format; var psb = new PSB(inputPath); if (psb.TypeHandler is BaseImageType imageType) { imageType.UnlinkToFile(psb, context, name, dirPath, outputUnlinkedPsb, order); } psb.TypeHandler.UnlinkToFile(psb, context, name, dirPath, outputUnlinkedPsb, order); if (outputUnlinkedPsb) { psb.Merge(); psbSavePath = Path.ChangeExtension(inputPath, ".unlinked.psb"); //unlink only works with motion.psb so no need for ext rename File.WriteAllBytes(psbSavePath, psb.Build()); } return(psbSavePath); }
public void UnlinkToFile(PSB psb, FreeMountContext context, string name, string dirPath, bool outputUnlinkedPsb = true, PsbLinkOrderBy order = PsbLinkOrderBy.Name) { //TODO: }
public override void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention) { LinkImages(psb, context, resPaths, baseDir, order, true); }
public void Link(PSB psb, FreeMountContext context, IList <string> resPaths, string baseDir = null, PsbLinkOrderBy order = PsbLinkOrderBy.Convention) { }