/// <summary> /// MoveToTree moves files in fromDir to a directory structure created in toDirRoot /// using the file's name as names for the folders in the directory structure /// </summary> /// <param name="fromDir">original directory</param> /// <param name="toDirRoot">root of the new directory structure </param> /// <param name="filter"></param> /// <param name="remove"></param> /// <returns></returns> public static int MoveToTree(string fromDir, string toDirRoot, string filter = "*.jpg", string remove = "") { ImageTreeFile dest; RaiFile source; int count = 0; foreach (var file in Directory.EnumerateFiles(new RaiFile(fromDir).FullName, filter)) { dest = new ImageTreeFile(file.Replace(remove, "")); dest.Path = new RaiFile(toDirRoot).FullName; source = new RaiFile(file); dest.mv(source); Console.WriteLine($"{source.FullName} moved to {dest.FullName}"); count++; } return(count); }
/// <summary>get first file that is a match in the filesystem</summary> /// <param name="extensions">comma seperated string with extensions</param> /// <param name="colorInfo">null by default; will be wildcarded if null</param> /// <returns>false if no file exists for any passed-in extensions - extends the ImageTreeFile accordingly otherwise and returns true</returns> public bool ExtendToFirstExistingFile(string extensions, ColorInfo colorInfo = null) { //try //{ var itf = new ImageTreeFile(FullName); itf.Color = colorInfo ?? new ColorInfo("#0DEAD0"); itf.Ext = "*"; var searchPattern = colorInfo == null?itf.NameWithExtension.Replace("_0DEAD0", "*") : itf.NameWithExtension; string[] dirEntries = Directory.GetFileSystemEntries(Path, searchPattern); string[] extArray = extensions.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); if (extArray.Length > 0) { foreach (var dirEntry in dirEntries) { itf = new ImageTreeFile(dirEntry); foreach (string extension in extArray) { if (extension == itf.Ext) { Ext = extension; Color = itf.Color; if (ImageNumber == NoImageNumber) // BildInArbeit.tiff requested; BildInArbeit_01.tiff exists => take it { ImageNumber = new ImageTreeFile(dirEntry).ImageNumber; } return(true); } } } } //} //catch (DirectoryNotFoundException) { } //catch (FileNotFoundException) { } //catch (Exception) { } return(false); }
/// <summary> /// creates tiles from a master image; master image stays unaffected /// </summary> /// <param name="master">full qualifying name with path</param> /// <param name="tileWidth">width of a tile in permille to cut out of the master; 0..1000</param> /// <param name="tileHeight">hight of a tile in permille to cut out of the master; 0..1000</param> /// <param name="resizeWidth">0 if no resize requested; in px</param> /// <param name="resizeHeight">0 if no resize requested; in px</param> /// <param name="adaptive">true|false</param> /// <param name="quality">ie "95%"</param> /// <param name="strip">remove metainfo from tiles if true</param> /// <param name="sharpen"></param> /// <param name="asharpen"></param> /// <param name="unsharp">unsharpmask if sharpening is requested or else null; ie "1.2x0.9+1.5+0.04"</param> /// <param name="destFiles">complete path of destination file; has to contain %d</param> /// <param name="deleteFirst">true|false</param> /// <returns>0 if IM call was successful; else errorcode</returns> public int CreateTiles(ImageTreeFile master, int tileWidth, int tileHeight, int resizeWidth, int resizeHeight, bool adaptive, string quality, bool strip, string sharpen, string asharpen, string unsharp, ImageTreeFile destFiles, bool deleteFirst) { System.Drawing.Size size = default(System.Drawing.Size); #region delete old tiles if necessary if (deleteFirst) { #region assume that file pattern has to be updated if resizeWidth or resizeHeight are set to 0 (autocalc) // code duplication (see below) tolerated as trade-off for better performance if (resizeWidth == 0 || resizeHeight == 0) { size = GetSize(master.FullName); #region handle no resize requested // this can fail, e.g. if the image size is not integer-dividable by 8 and tile width is requested as 0.125 if (resizeWidth == 0) { resizeWidth = size.Width / (int)(Math.Round(1000 / (float)tileWidth, 0)); } if (resizeHeight == 0) { resizeHeight = size.Height / (int)(Math.Round(1000 / (float)tileHeight, 0)); } destFiles.NameExt = resizeWidth.ToString() + "x" + resizeHeight.ToString(); #endregion } #endregion string[] oldFiles = Directory.GetFiles(destFiles.Path, destFiles.NameWithExtension.Replace("%d", "*")); foreach (string oldFile in oldFiles) { #region robust delete try { File.Delete(oldFile); } #pragma warning disable 0168 catch (Exception fileInUse) { try { Thread.Sleep(100); File.Delete(oldFile); } catch (Exception fileStillInUse) { try { Thread.Sleep(300); File.Delete(oldFile); } catch (Exception giveItUp) { continue; } } } #pragma warning restore 0168 #endregion } } #endregion else if (File.Exists(destFiles.FullName.Replace("%d", "0"))) // destFiles.NameExt is taken as is - no correction applied if necessary { return(0); // sb created it before; don't do it again } if (size.IsEmpty) // otherwise: was done above already (deleteFirst branch); duplicate code tolerated { size = GetSize(master.FullName); #region handle no resize requested // this can fail, e.g. if the image size is not integer-dividable by 8 and tile width is requested as 0.125 if (resizeWidth == 0) { resizeWidth = size.Width / (int)(Math.Round(1000 / (float)tileWidth, 0)); } if (resizeHeight == 0) { resizeHeight = size.Height / (int)(Math.Round(1000 / (float)tileHeight, 0)); } destFiles.NameExt = resizeWidth.ToString() + "x" + resizeHeight.ToString(); #endregion } #region create new fullsize image in the requested size from master and scale up to the implicitely requested total size if necessary int totalWidth = (int)(Math.Round(1000 / (float)tileWidth, 0) * resizeWidth); int totalHeight = (int)(Math.Round(1000 / (float)tileHeight, 0) * resizeHeight); string options = ""; //if (totalWidth == 480 && totalHeight == 600 && size.Width == 2080 && size.Height == 2600) // combination known to create moirees // options += "-filter Mitchell"; // fixed: don't use -adaptive-resize; configure in template if (totalWidth != size.Width || totalHeight != size.Height) { // scaling of master is necessary - upscaling causes loss of quality if (adaptive) { options = options + " -adaptive-resize " + totalWidth.ToString() + "x" + totalHeight.ToString(); } else { options = options + " -resize " + totalWidth.ToString() + "x" + totalHeight.ToString(); } } if (asharpen != null && asharpen.Length > 0) { options = options + " -adaptive-sharpen " + asharpen; } else if (sharpen != null && sharpen.Length > 0) { options = options + " -sharpen " + sharpen; } else if (unsharp != null && unsharp.Length > 0) { options = options + " -unsharp " + unsharp; } if (strip) { options = "-strip " + options; } ImageTreeFile total = new ImageTreeFile(destFiles.FullName); total.Ext = "png"; // important decision: tiles go via png (png is under suspicion to have a problem with some red levels) total.TileNumber = "all"; int rc = Convert(options, master.FullName, total.FullName, true); #endregion #region cut tiles if (rc == 0) { options = "-crop " + resizeWidth.ToString() + "x" + resizeHeight.ToString(); if (!string.IsNullOrEmpty(quality)) { options = "-quality " + quality + "% " + options; } rc = Convert(options, total.FullName, destFiles.FullName, true); } #endregion #region clean up total.rm(); #endregion #region old solution // options = "-crop " + w.ToString() + "x" + h.ToString(); //if (resizeWidth > 0 && resizeHeight > 0) //{ // if (adaptive) // options = options + " -adaptive-resize " + resizeWidth.ToString() + "x" + resizeHeight.ToString(); // else options = options + " -resize " + resizeWidth.ToString() + "x" + resizeHeight.ToString(); //} //if (asharpen != null && asharpen.Length > 0) // options = options + " -adaptive-sharpen " + asharpen; //else if (sharpen != null && sharpen.Length > 0) // options = options + " -sharpen " + sharpen; //else if (unsharp != null && unsharp.Length > 0) // options = options + " -unsharp " + unsharp; //if (strip) // options = "-strip " + options; //if (quality != null && quality.Length > 0) // options = "-quality " + quality + "% " + options; //return Convert(options, master, destFiles.FullName, true); #endregion #region optimization for png images - NOT IMPLEMENTED YET //idea: apply to all png files in this directory ... or use the same searchPattern as for delete old tiles above //if (tSet.Ext == "png" && tSet.Compress) // rc = rc & new ImageMagick().Optipng(dest.FullName); #endregion return(rc); }