public void Test_ToBitmap() { using (MagickImage image = new MagickImage(MagickColors.Red, 10, 10)) { ExceptionAssert.Throws <NotSupportedException>(delegate() { image.ToBitmap(ImageFormat.Exif); }); Bitmap bitmap = image.ToBitmap(); Assert.AreEqual(ImageFormat.MemoryBmp, bitmap.RawFormat); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(0, 0)); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(5, 5)); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(9, 9)); bitmap.Dispose(); Test_ToBitmap(image, ImageFormat.Bmp); Test_ToBitmap(image, ImageFormat.Gif); Test_ToBitmap(image, ImageFormat.Icon); Test_ToBitmap(image, ImageFormat.Jpeg); Test_ToBitmap(image, ImageFormat.Png); Test_ToBitmap(image, ImageFormat.Tiff); } using (MagickImage image = new MagickImage(new MagickColor(0, Quantum.Max, Quantum.Max, 0), 10, 10)) { Bitmap bitmap = image.ToBitmap(); Assert.AreEqual(ImageFormat.MemoryBmp, bitmap.RawFormat); MagickColor color = MagickColor.FromRgba(0, 255, 255, 0); ColorAssert.AreEqual(color, bitmap.GetPixel(0, 0)); ColorAssert.AreEqual(color, bitmap.GetPixel(5, 5)); ColorAssert.AreEqual(color, bitmap.GetPixel(9, 9)); bitmap.Dispose(); } }
public async Task <Stream> GenerateProfileBackgroundAsync(CachedUser user, Stream backgroundStream) { using var image = new MagickImage(_dark, 500, 500); using var tempBackgroundImage = new MagickImage(backgroundStream); tempBackgroundImage.Resize(new MagickGeometry { Width = 500, Height = 250, IgnoreAspectRatio = false, FillArea = true }); using var backgroundImageLayer = new MagickImage(MagickColors.Black, 500, 250); backgroundImageLayer.Draw(new DrawableComposite(0, 0, CompositeOperator.Over, tempBackgroundImage)); image.Draw(new DrawableComposite(0, 0, backgroundImageLayer)); image.Draw(new Drawables().Rectangle(0, 0, 500, 250).FillColor(MagickColor.FromRgba(0, 0, 0, 128))); await AddAvatarAndUsernameAsync(image, user); var imageStream = new MemoryStream(); image.Write(imageStream, MagickFormat.Png); imageStream.Position = 0; return(imageStream); }
private void DrawBboxes(byte[] photo, Bbox[] bboxes, ref Image img) { using (var image = new MagickImage(photo)) { var drawables = new Drawables(); drawables.StrokeWidth(ViewImage.Source.Height >= 1000 ? 8 : 2); drawables.FillColor(MagickColor.FromRgba(255, 255, 255, 0)); drawables.StrokeColor(MagickColor.FromRgb(255, 0, 0)); foreach (var bbox in bboxes) { drawables.Rectangle(bbox.X, bbox.Y, bbox.X + bbox.Width, bbox.Y + bbox.Height ); } image.Draw(drawables); using (var ms = new MemoryStream(image.ToByteArray())) { var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.StreamSource = ms; bitmap.EndInit(); img.Source = bitmap; } } }
public byte[] TakeImage() { using (var image = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), PageSize.Width, PageSize.Height)) { image.Format = MagickFormat.Png32; for (var x = 0; x < HorizontalSnaps; x++) { for (var y = 0; y < VerticalSnaps; y++) { Driver.SetOffset(x * ViewSize.Width, y * ViewSize.Height); using (var part = new MagickImage(TakesScreenshot.GetScreenshot().AsByteArray)) { UpdateOffsetX(out int oldOffsetX, out int diffX); UpdateOffsetY(out int oldOffsetY, out int diffY); var imageRectangle = new Rectangle(OffsetX, OffsetY, ViewSize.Width, ViewSize.Height); var horizontalRedundancy = Math.Max(0, imageRectangle.Right - PageSize.Width) * Math.Min(x, 1); var verticalRedundancy = Math.Max(0, imageRectangle.Bottom - PageSize.Height) * Math.Min(y, 1); image.Composite(part, OffsetX - horizontalRedundancy, OffsetY - verticalRedundancy, CompositeOperator.Copy); } } } return(image.ToByteArray()); } }
public void Process() { using (var bg = new MagickImage(MagickColor.FromRgba(255, 255, 255, 255), width, height)) { using (var image = new MagickImage(input)) { if (image.HasAlpha == false) { image.Alpha(AlphaOption.Opaque); } using (var cover = image.Clone()) { MagickGeometry resize = new MagickGeometry(width + "x" + height + "^"); image.Resize(resize); image.Extent(width, height, Gravity.Center); image.Blur(80, 30); bg.Composite(image, 0, 0, CompositeOperator.Over); MagickGeometry centerResize = new MagickGeometry(height * 0.7 + "x" + height * 0.7); cover.Resize(centerResize); using (var coverShadow = cover.Clone()) { coverShadow.BackgroundColor = MagickColor.FromRgba(192, 192, 192, 192); coverShadow.Shadow(50, 50, 10, new Percentage(90)); bg.Composite(coverShadow, Gravity.Center, CompositeOperator.Over); } bg.Composite(cover, Gravity.Center, CompositeOperator.Over); } } bg.Write(output); } }
public void GenerateImage(string achievementName, long gs, AchievementType type, ulong imageID) { // first determine background image path string backgroundImagePath; switch (type) { case AchievementType.XboxOneRare: backgroundImagePath = Configuration.PathAchievementXboxOneRareBackground; break; case AchievementType.Xbox360: backgroundImagePath = Configuration.PathAchievementXbox360Background; break; default: backgroundImagePath = Configuration.PathAchievementXboxOneBackground; break; } // passing the relative path was breaking it, so now just going to pass it the file stream instead string path = Path.Combine(Directory.GetCurrentDirectory(), backgroundImagePath); using (var backgroundStream = new FileStream(path, FileMode.Open)) { // now do stuff with the image using (MagickImage image = new MagickImage(backgroundImagePath)) { MagickImage headerLayer = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), image.Width, image.Height); if (type == AchievementType.XboxOne || type == AchievementType.XboxOneRare) { headerLayer.Settings.FontFamily = "Segoe UI"; headerLayer.Settings.FontPointsize = 36; headerLayer.Settings.TextGravity = Gravity.Southwest; headerLayer.Settings.FillColor = MagickColor.FromRgb(255, 255, 255); } if (type == AchievementType.XboxOne || type == AchievementType.Xbox360) { var s = $"{gs} - {achievementName}"; headerLayer.Annotate(s, new MagickGeometry(225, 30, 700, 80), Gravity.West); } else if (type == AchievementType.XboxOneRare) { int rarePercent; Random r = new Random(); rarePercent = r.Next(1, 5); headerLayer.Annotate($"Rare achievement unlocked - {rarePercent}%", new MagickGeometry(155, 5, 400, 70), Gravity.West); headerLayer.Annotate($"{gs} - {achievementName}", new MagickGeometry(195, 55, 400, 70), Gravity.West); } image.Composite(headerLayer, CompositeOperator.Over); image.Write(GenerateImagePath(imageID)); } } // increment the generation counter GenerationCounter++; }
/// <summary> /// Dumps to console. /// </summary> /// <param name="gradientFinder">The gradient finder.</param> private static void DumpToConsole(GradientFinder gradientFinder) { foreach (var part in gradientFinder.GradientParts) { var magickColor = MagickColor.FromRgba((byte)part.Red, (byte)part.Green, (byte)part.Blue, (byte)part.Alpha); Console.WriteLine($"{(part.Position.ToString("00.00", CultureInfo.InvariantCulture) + "%").PadLeft(7)} - {magickColor}"); } }
public MagickGeometry MagickResize() { MagickGeometry size = new MagickGeometry(ResizedWidth, ResizedHeight); using (MagickImage image = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), Width, Height)) { image.Resize(size); return(size); } }
///<inheritdoc cref="IMagick.MakeTransperent(byte[])"/> public string MakeTransperent(byte[] img) { using (var image = new MagickImage(img)) { image.Format = MagickFormat.Png; image.Alpha(AlphaOption.Set); image.ColorFuzz = new Percentage(10); image.Opaque(MagickColors.White, MagickColor.FromRgba(0, 0, 0, 0)); return(image.ToBase64()); } }
public MagickGeometry MagickResize() { var size = new MagickGeometry(ResizedWidth, ResizedHeight); using (var image = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), Width, Height)) { image.FilterType = FilterType.Cubic; image.Resize(size); return(size); } }
public TitanicIMArray(ITitanicArrayConfig <T> config) { this.config = config; TSize = GetSizeInBytes(config.DataSerializer); pixelsPerItem = IntCeil(TSize, bytesPerPixel); long maxPixels = config.Capacity * pixelsPerItem; FindDimensions(maxPixels, out Width, out Height); MagickNET.SetTempDirectory(Path.GetDirectoryName(config.BackingStoreFileName)); im = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), Width, Height); pixels = im.GetPixels(); }
private void AddBackground(MagickImage?backgroundImage, MagickImage image, ProfileInfo profileInfo) { using var background = backgroundImage ?? new MagickImage(_defaultBackgroundPath); var backgroundDrawable = new DrawableComposite ( (double)(background.Width - 500) / 2, (double)(background.Height - 250) / 2, background ); image.Draw(backgroundDrawable); var dim = (float)profileInfo.Dim / 100 * 255; image.Draw(new Drawables().Rectangle(0, 0, 500, 250).FillColor(MagickColor.FromRgba(0, 0, 0, (byte)dim))); }
public void Test_ToBitmap() { using (IMagickImage image = new MagickImage(MagickColors.Red, 10, 10)) { ExceptionAssert.Throws <NotSupportedException>(() => { image.ToBitmap(ImageFormat.Exif); }); using (Bitmap bitmap = image.ToBitmap()) { Assert.AreEqual(ImageFormat.MemoryBmp, bitmap.RawFormat); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(0, 0)); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(5, 5)); ColorAssert.AreEqual(MagickColors.Red, bitmap.GetPixel(9, 9)); } Test_ToBitmap(image, ImageFormat.Bmp); Test_ToBitmap(image, ImageFormat.Gif); Test_ToBitmap(image, ImageFormat.Icon); Test_ToBitmap(image, ImageFormat.Jpeg); Test_ToBitmap(image, ImageFormat.Png); Test_ToBitmap(image, ImageFormat.Tiff); } using (IMagickImage image = new MagickImage(new MagickColor(0, Quantum.Max, Quantum.Max, 0), 10, 10)) { using (Bitmap bitmap = image.ToBitmap()) { Assert.AreEqual(ImageFormat.MemoryBmp, bitmap.RawFormat); MagickColor color = MagickColor.FromRgba(0, 255, 255, 0); ColorAssert.AreEqual(color, bitmap.GetPixel(0, 0)); ColorAssert.AreEqual(color, bitmap.GetPixel(5, 5)); ColorAssert.AreEqual(color, bitmap.GetPixel(9, 9)); } } using (IMagickImage image = new MagickImage(Files.CMYKJPG)) { using (Bitmap bitmap = image.ToBitmap()) { Assert.AreEqual(ImageFormat.MemoryBmp, bitmap.RawFormat); ColorAssert.AreEqual(new MagickColor("#26ffb1"), bitmap.GetPixel(1142, 42)); } } }
private void AddFrameToCollection(Bitmap frame, MagickImageCollection collection) { using (MemoryStream ms = new MemoryStream()) { frame.Save(ms, ImageFormat.Png); ms.Position = 0; MagickImage mi = new MagickImage(ms, MagickFormat.Png) { AnimationDelay = 10, BackgroundColor = MagickColor.FromRgba(Properties.Settings.Default.TextBackground.R, Properties.Settings.Default.TextBackground.G, Properties.Settings.Default.TextBackground.B, Properties.Settings.Default.TextBackground.A), GifDisposeMethod = GifDisposeMethod.Background, AnimationTicksPerSecond = 200 }; collection.Add(mi); } }
private void RemoveNoise(MagickImage image) { using (MagickImage second = image.Clone()) { second.ColorSpace = ColorSpace.Gray; second.Negate(); second.AdaptiveThreshold(FilterSize, FilterSize, FilterOffset); second.ContrastStretch((Percentage)0); if (SmoothingThreshold != null) { second.Blur(SmoothingThreshold.Value.ToDouble() / 100, Quantum.Max); second.Level(SmoothingThreshold.Value, new Percentage(100)); } image.Composite(second, CompositeOperator.CopyAlpha); } image.Opaque(MagickColor.FromRgba(255, 255, 255, 0), BackgroundColor); image.Alpha(AlphaOption.Off); }
public void ExportTextures(CnkLOD chunk) { string name = Path.GetFileNameWithoutExtension(chunk.Name); if (name == null) { return; } string directory = ResourceDir + "/Terrain/" + name.Split('_')[0]; if (!Directory.Exists(directory + @"/Textures")) { Directory.CreateDirectory(directory + @"/Textures"); } MontageSettings montageSettings = new MontageSettings(); montageSettings.TileGeometry = new MagickGeometry(2, 2); montageSettings.Geometry = new MagickGeometry(512, 512); montageSettings.BackgroundColor = MagickColor.FromRgba(0, 0, 0, 0); montageSettings.BorderColor = MagickColor.FromRgba(0, 0, 0, 0); montageSettings.BorderWidth = 0; // Color Map string colorMapPath = directory + @"/Textures/" + name + "_colornx" + ".dds"; if (!File.Exists(colorMapPath)) { CreateTexture(montageSettings, colorMapPath, chunk.Textures.Select(texture => texture.ColorNXMap.ToArray())); } // Specular map string specMapPath = directory + @"/Textures/" + name + "_specny" + ".dds"; if (!File.Exists(specMapPath)) { CreateTexture(montageSettings, specMapPath, chunk.Textures.Select(texture => texture.SpecNyMap.ToArray())); } }
private MagickImage GenerateOverlay() { Size resolution = new Size(gif.Width, gif.Height); Rectangle cropValues = new Rectangle( ParseInt(textBoxCropLeft.Text), ParseInt(textBoxCropTop.Text), ParseInt(textBoxCropRight.Text), ParseInt(textBoxCropBottom.Text) ); cropRect = new Rectangle( cropValues.X, cropValues.Y, resolution.Width - cropValues.Right, resolution.Height - cropValues.Bottom ); MagickImage overlay = new MagickImage( MagickColor.FromRgba(255, 0, 0, 128), resolution.Width, resolution.Height ); // draw transparent rectangle overlay.Composite( new MagickImage( MagickColor.FromRgba(0, 0, 0, 0), cropRect.Width, cropRect.Height ), cropRect.X, cropRect.Y ); this.overlay = overlay; return(overlay); }
public async Task dank(CommandContext ctx) { await ctx.TriggerTypingAsync(); using (var client = new WebClient()) { Stream stream = await client.OpenReadTaskAsync(new Uri(ctx.User.AvatarUrl)); var ava = new MagickImage(stream); Stream streamm = new MemoryStream(); var img = new MagickImage(MagickColor.FromRgba(255, 0, 0, 255), ava.Width, ava.Height); img.Format = MagickFormat.Png64; img.Composite(ava, 50, 50, CompositeOperator.SrcOver); var memory = new MemoryStream(img.ToByteArray()); await ctx.RespondWithFileAsync("test.png", memory, "test"); // Dispose of everything used await memory.DisposeAsync(); await stream.DisposeAsync(); img.Dispose(); } }
public void SetMagickImage(bool extremePrecision) { var mi = new MagickImage((Bitmap)Image) { ColorSpace = Watcher.ColorSpace }; if (!extremePrecision) { var mGeo = new MagickGeometry( (int)Math.Round(WatchZone.CropGeometry.Width), (int)Math.Round(WatchZone.CropGeometry.Height)) { IgnoreAspectRatio = true }; mi.Scale(mGeo); mi.RePage(); } else { var underlay = new MagickImage(MagickColor.FromRgba(0, 0, 0, 0), (int)Screen.Geometry.Width, (int)Screen.Geometry.Height); underlay.Composite(mi, new PointD(WatchZone.Geometry.Width, WatchZone.Geometry.Height), CompositeOperator.Copy); underlay.RePage(); var mGeo = Scanner.CropGeometry.ToMagick(false); mGeo.IgnoreAspectRatio = true; underlay.Resize(mGeo); underlay.RePage(); underlay.Trim(); mi = underlay; } if (Watcher.Equalize) { mi.Equalize(); } MagickImage = mi; }
public void Resize(int width, int height, bool expand = true, Gravity position = Gravity.Center) { using (MagickImage image = new MagickImage(_source)) { image.Resize(width, height); if (expand) { image.Extent( width, height, position, MagickColor.FromRgba( image.BackgroundColor.R, image.BackgroundColor.G, image.BackgroundColor.B, image.BackgroundColor.A ) ); } image.Write(_destination); } }
public static MagickColor FromNetColor(Color c) { return(MagickColor.FromRgba(c.R, c.G, c.B, c.A)); }
public static void ExportTextures(ForgelightGame forgelightGame, CnkLOD chunk, string directory) { string name = Path.GetFileNameWithoutExtension(chunk.Name); if (name == null) { return; } directory += "/" + name.Split('_')[0]; if (!Directory.Exists(directory + @"/Textures")) { Directory.CreateDirectory(directory + @"/Textures"); } MontageSettings montageSettings = new MontageSettings(); montageSettings.TileGeometry = new MagickGeometry(2, 2); montageSettings.Geometry = new MagickGeometry(512, 512); montageSettings.BackgroundColor = MagickColor.FromRgba(0, 0, 0, 0); montageSettings.BorderColor = MagickColor.FromRgba(0, 0, 0, 0); montageSettings.BorderWidth = 0; //TODO Code Duplication //Color Map string colorMapPath = directory + @"/Textures/" + name + "_colornx" + ".dds"; if (!File.Exists(colorMapPath)) { using (MagickImageCollection stitchedColorMap = new MagickImageCollection()) { foreach (CnkLOD.Texture texture in chunk.Textures) { MagickImage textureQuad = new MagickImage(texture.ColorNXMap.ToArray()); stitchedColorMap.Add(textureQuad); } using (MagickImage result = stitchedColorMap.Montage(montageSettings)) { result.Write(colorMapPath); } } } //TODO code duplication //Specular map string specMapPath = directory + @"/Textures/" + name + "_specny" + ".dds"; if (!File.Exists(specMapPath)) { using (MagickImageCollection stitchedSpecMap = new MagickImageCollection()) { foreach (CnkLOD.Texture texture in chunk.Textures) { MagickImage textureQuad = new MagickImage(texture.SpecNyMap.ToArray()); stitchedSpecMap.Add(textureQuad); } using (MagickImage result = stitchedSpecMap.Montage(montageSettings)) { result.Write(specMapPath); } } } }
private static void Main(string[] args) { #if NETCOREAPP // .NET Core Appの場合、Shift JISなども扱えるようにするためにエンコーディングプロバイダを追加 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); #endif Parser.Default.ParseArguments <Options>(args) .WithParsed(opt => { // オプションチェック var target = (opt.Target == null ? "pair" : opt.Target.ToLower()); if (opt.PairMargin != null && target != "pair") { Console.Error.WriteLine($"ERROR: pair marginは target = 'pair' の場合のみ指定できます。"); return; } if (opt.FaceSize != null && target != "p0-face" && target != "p1-face") { Console.Error.WriteLine($"ERROR: face sizeは target = 'p0-face' or 'p1-face' の場合のみ指定できます。"); return; } var pairMargin = opt.PairMargin.GetValueOrDefault(64); if (opt.PairMargin < 0) { Console.Error.WriteLine($"ERROR: pair margin指定 '{opt.PairMargin}' が正しくありません。 0以上の整数で指定してください。"); return; } Tuple <int, int> faceSizes; if (opt.Padding != null) { var matched = Regex.Match(opt.Padding, @"^(\d{1,5}),(\d{1,5})$"); if (matched.Success) { faceSizes = Tuple.Create( int.Parse(matched.Groups[1].Value) , int.Parse(matched.Groups[2].Value) ); } else { Console.Error.WriteLine($"ERROR: face size指定 '{opt.Padding}' が正しくありません。 '120,100' のようなフォーマットで指定してください。"); return; } } else { faceSizes = Tuple.Create(120, 120); } // 出力先決定 var outputPath = opt.OutputPath ?? $"./{target}.png"; Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); // シェルを読み込む Shell shell; var interimOutputDirPathForDebug = (opt.Debug ? Path.Combine(Path.GetDirectoryName(outputPath), "_interim") : null); if (Ghost.IsGhostDir(opt.TargetDirPath)) { // ゴーストフォルダのルートが指定された場合 var ghost = Ghost.Load(opt.TargetDirPath); var shellDirPath = Path.Combine(ghost.DirPath, ghost.CurrentShellRelDirPath); shell = Shell.Load(shellDirPath, ghost.SakuraDefaultSurfaceId, ghost.KeroDefaultSurfaceId, interimOutputDirPathForDebug: interimOutputDirPathForDebug); } else if (Shell.IsShellDir(opt.TargetDirPath)) { // シェルフォルダが指定された場合 var shellDirPath = opt.TargetDirPath; shell = Shell.Load(shellDirPath, 0, 10, interimOutputDirPathForDebug: interimOutputDirPathForDebug); // サーフェス番号はデフォルトの0, 10とする } else { Console.Error.WriteLine($"ERROR: 指定したフォルダ '{opt.TargetDirPath}' が、ゴーストフォルダでもシェルフォルダでもありませんでした。"); return; } // 出力 MagickImage dest; switch (target) { case "pair": var sakuraImg = shell.DrawSurface(shell.SakuraSurfaceModel); var keroImg = shell.DrawSurface(shell.KeroSurfaceModel); // kero側がダミー画像でないかどうかを判定 var keroIsDummy = false; if (keroImg.Width <= 2 && keroImg.Height <= 2) { keroIsDummy = true; // 縦横2px以下の画像はダミー } sakuraImg.Extent(sakuraImg.Width + keroImg.Width + (keroIsDummy ? 0 : pairMargin), sakuraImg.Height, gravity: Gravity.East, backgroundColor: MagickColor.FromRgba(255, 255, 255, 0)); sakuraImg.Composite(keroImg, Gravity.Southwest, CompositeOperator.Over); dest = sakuraImg; break; case "p0": dest = shell.DrawSurface(shell.SakuraSurfaceModel); break; case "p1": dest = shell.DrawSurface(shell.KeroSurfaceModel); break; case "p0-face": dest = shell.DrawFaceImage(shell.SakuraSurfaceModel, faceSizes.Item1, faceSizes.Item2); break; case "p1-face": dest = shell.DrawFaceImage(shell.KeroSurfaceModel, faceSizes.Item1, faceSizes.Item2); break; default: Console.Error.WriteLine($"ERROR: target '{opt.Target}' は処理できません。"); return; } // パディングを入れる Tuple <int, int, int, int> paddings; if (opt.Padding != null) { var matched = Regex.Match(opt.Padding, @"^(\d{1,5}),(\d{1,5}),(\d{1,5}),(\d{1,5})$"); if (matched.Success) { paddings = Tuple.Create( int.Parse(matched.Groups[1].Value) , int.Parse(matched.Groups[2].Value) , int.Parse(matched.Groups[3].Value) , int.Parse(matched.Groups[4].Value) ); } else { Console.Error.WriteLine($"ERROR: padding指定 '{opt.Padding}' が正しくありません。 '16,32,0,16' のようなフォーマットで指定してください。"); return; } } else { if (target == "p0-face" || target == "p1-face") { paddings = Tuple.Create(0, 0, 0, 0); } else { paddings = Tuple.Create(16, 32, 0, 32); } } var topPadding = paddings.Item1; var rightPadding = paddings.Item2; var bottomPadding = paddings.Item3; var leftPadding = paddings.Item4; dest.Extent(dest.Width + rightPadding, dest.Height + topPadding, gravity: Gravity.Southwest, backgroundColor: MagickColor.FromRgba(255, 255, 255, 0)); dest.Extent(dest.Width + leftPadding, dest.Height + bottomPadding, gravity: Gravity.Northeast, backgroundColor: MagickColor.FromRgba(255, 255, 255, 0)); dest.RePage(); dest.Write(outputPath); Console.WriteLine($"output -> {outputPath}"); }) .WithNotParsed(err => { Debug.WriteLine(err); }); }
private void RefreshThumbnail() { Geometry minGeo = Geometry.Min(Scanner.CropGeometry, GetScaledGeometry(Geometry.Blank)); MagickImage mi = new MagickImage(CurrentFrame); if (!Scanner.VideoGeometry.Contains(Scanner.CropGeometry)) { mi.Extent(Scanner.CropGeometry.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR); } else { mi.Crop(Scanner.CropGeometry.ToMagick(), STANDARD_GRAVITY); } mi.RePage(); if (DdlWatchZone.SelectedIndex > 0) { var wi = (WatchImage)DdlWatchZone.SelectedItem; var tGeo = wi.WatchZone.CropGeometry; tGeo.Update(-Scanner.CropGeometry.X, -Scanner.CropGeometry.Y); var baseMGeo = new MagickGeometry(100, 100, (int)Math.Round(tGeo.Width), (int)Math.Round(tGeo.Height)); tGeo.Update(-100, -100, 200, 200); mi.Extent(tGeo.ToMagick(), STANDARD_GRAVITY, EXTENT_COLOR); using (var baseM = new MagickImage( MagickColor.FromRgba(0, 0, 0, 0), baseMGeo.Width, baseMGeo.Height)) using (var overlay = new MagickImage( MagickColor.FromRgba(170, 170, 170, 223), baseMGeo.Width + 200, baseMGeo.Height + 200)) { baseM.ColorSpace = ColorSpace.RGB; overlay.ColorSpace = ColorSpace.RGB; overlay.Composite(baseM, new PointD(baseMGeo.X, baseMGeo.Y), CompositeOperator.Alpha); mi.Composite(overlay, CompositeOperator.Atop); } mi.RePage(); minGeo = minGeo.Min(GetScaledGeometry(tGeo)); if (CkbViewDelta.Checked) { using (var deltaImage = wi.MagickImage.Clone()) { mi.ColorSpace = wi.Watcher.ColorSpace; deltaImage.ColorSpace = wi.Watcher.ColorSpace; mi.Crop(baseMGeo, STANDARD_GRAVITY); //mi.Write(@"E:\fuck0.png"); //deltaImage.Write(@"E:\fuck1.png"); mi.Alpha(AlphaOption.Off); // Why is this necessary? It wasn't necessary before. //mi.Write(@"E:\fuck2.png"); if (wi.Watcher.Equalize) { deltaImage.Equalize(); mi.Equalize(); } deltaImage.RePage(); mi.RePage(); //mi.Write(@"E:\fuck3.png"); //deltaImage.Write(@"E:\fuck4.png"); LblDeltas.Text = mi.Compare(deltaImage, ErrorMetric.PeakSignalToNoiseRatio).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.NormalizedCrossCorrelation).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.Absolute).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.Fuzz).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.MeanAbsolute).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.MeanSquared).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.StructuralDissimilarity).ToString("0.####") + "\r\n" + mi.Compare(deltaImage, ErrorMetric.StructuralSimilarity).ToString("0.####"); mi.Composite(deltaImage, CompositeOperator.Difference); //mi.Write(@"E:\fuck5.png"); //deltaImage.Write(@"E:\fuck6.png"); } minGeo = minGeo.Min(GetScaledGeometry(wi.WatchZone.CropGeometry)); } } if (mi.Width > minGeo.Size.ToDrawing().Width || mi.Height > minGeo.Size.ToDrawing().Height) { var mGeo = minGeo.ToMagick(); mGeo.IgnoreAspectRatio = false; mi.ColorSpace = ColorSpace.Lab; mi.FilterType = DEFAULT_SCALE_FILTER; mi.Resize(mGeo); } ThumbnailBox.Size = minGeo.Size.ToDrawing(); ThumbnailBox.Image = mi.ToBitmap(System.Drawing.Imaging.ImageFormat.MemoryBmp); }
public void Recognize() { var width = _image.Width; var height = _image.Height; KeyValuePair <ulong[], ulong[]>[,] matrix = new KeyValuePair <ulong[], ulong[]> [width, height]; for (var y = 0; y < height; y++) { IndexRow(y, width); } for (int x = 0; x < width; x++) { IndexColumn(x, height); } for (var y = 0; y < height; y++) { if (y == 574) { var roww = GetRow(y, width); var levelss = _sequenceToItsLocalElementLevelsConverter.Convert(roww); var l276 = levelss[276]; var l277 = levelss[277]; var l278 = levelss[278]; } var row = SaveRow(y, width); var x = 0; var stack = new Stack <ulong>(); StopableSequenceWalker.WalkRight(row, _links.GetSource, _links.GetTarget, _links.IsPartialPoint, enteredElement => { stack.Push(enteredElement); }, exitedElement => { stack.Pop(); }, checkedElement => true, element => { stack.Push(element); var pair = new KeyValuePair <ulong[], ulong[]>(stack.ToArray(), default); stack.Pop(); matrix[x++, y] = pair; return(true); }); } for (int x = 0; x < width; x++) { var column = SaveColumn(x, height); var y = 0; var stack = new Stack <ulong>(); StopableSequenceWalker.WalkRight(column, _links.GetSource, _links.GetTarget, _links.IsPartialPoint, enteredElement => { stack.Push(enteredElement); }, exitedElement => { stack.Pop(); }, checkedElement => true, element => { var pair = matrix[x, y]; stack.Push(element); pair = new KeyValuePair <ulong[], ulong[]>(pair.Key, stack.ToArray()); stack.Pop(); matrix[x, y++] = pair; return(true); }); } // Sort sequences by usages and frequency var linksByUsages = new SortedDictionary <ulong, List <ulong> >(); var linksByFrequency = new SortedDictionary <ulong, List <ulong> >(); var any = _links.Constants.Any; var @continue = _links.Constants.Continue; var query = new Link <ulong>(any, any, any); _links.Each(link => { var linkIndex = _links.GetIndex(link); var usages = _links.Count(new ulong[] { any, linkIndex }); if (!linksByUsages.TryGetValue(usages, out List <ulong> linksByUsageList)) { linksByUsageList = new List <ulong>(); linksByUsages.Add(usages, linksByUsageList); } linksByUsageList.Add(linkIndex); ulong frequency = GetFrequency(link); if (!linksByFrequency.TryGetValue(frequency, out List <ulong> linksByFrequencyList)) { linksByFrequencyList = new List <ulong>(); linksByFrequency.Add(frequency, linksByFrequencyList); } linksByFrequencyList.Add(linkIndex); return(@continue); }, query); // Build matrix of levels on 2D plane (as in optimal variant algorithm) var levels = new ulong[width, height]; var topBottom = 0UL; var leftRight = 0UL; var bottomTop = 0UL; var rightLeft = 0UL; var lastX = width - 1; var lastY = height - 1; // We do not calculate edges to simplify the algorithm for (int y = 1; y < lastY; y++) { for (int x = 1; x < lastX; x++) { topBottom = GetFrequency(matrix[x, y - 1].Key[0], matrix[x, y].Key[0]); leftRight = GetFrequency(matrix[x - 1, y].Key[0], matrix[x, y].Key[0]); bottomTop = GetFrequency(matrix[x, y].Key[0], matrix[x, y + 1].Key[0]); rightLeft = GetFrequency(matrix[x, y].Key[0], matrix[x + 1, y].Key[0]); levels[x, y] = Math.Max(Math.Max(topBottom, leftRight), Math.Max(bottomTop, rightLeft)); } } // Print levels matrix //for (int y = 1; y < lastY; y++) //{ // for (int x = 1; x < lastX; x++) // { // Console.Write("{0:0000}", levels[x, y]); // Console.Write(' '); // } // Console.WriteLine(); //} // Black and white (split to two colors) var contrastedLevels = new ulong[width, height]; var minimum = ulong.MaxValue; var maximum = ulong.MinValue; for (int y = 1; y < lastY; y++) { for (int x = 1; x < lastX; x++) { var level = levels[x, y]; minimum = minimum > level ? level : minimum; } } for (int y = 1; y < lastY; y++) { for (int x = 1; x < lastX; x++) { var level = levels[x, y]; maximum = maximum < level ? level : maximum; } } var middle = (maximum + minimum) / 2; for (int y = 1; y < lastY; y++) { for (int x = 1; x < lastX; x++) { contrastedLevels[x, y] = levels[x, y] > middle ? 0UL : 1UL; // the most frequent should be background (zero) } } // Print contrasted levels matrix //for (int y = 1; y < lastY; y++) //{ // for (int x = 1; x < lastX; x++) // { // Console.Write("{0:0}", contrastedLevels[x, y]); // } // Console.WriteLine(); //} var outputImagePath = Path.ChangeExtension(_sourceImagePath, ".bf.png"); using (var outputImage = new MagickImage(MagickColor.FromRgba(0, 0, 0, 255), width, height)) { var pixels = outputImage.GetPixels(); for (int y = 1; y < lastY; y++) { for (int x = 1; x < lastX; x++) { if (contrastedLevels[x, y] > 0) { pixels.SetPixel(x, y, new byte[] { 255, 255, 255, 255 }); } } Console.WriteLine(); } outputImage.Write(outputImagePath); } // Get the largest repeated patterns with lowest frequency (level) }
public static GifData UserCreateGifData(string[] imageFrames) { if (imageFrames == null) { throw new ArgumentNullException(nameof(imageFrames)); } if (imageFrames.Length == 0) { throw new ArgumentException("Value cannot be an empty collection.", nameof(imageFrames)); } var filename = UserInputString("Output filename (blank if \"AnimationExport.gif\"):", "AnimationExport.gif"); Console.WriteLine(); var outputDir = UserInputPath("Output directory (blank if same as input directory):", Directory.GetParent(imageFrames[0]).FullName); Console.WriteLine(); int animationDuration; do { animationDuration = UserInputInt("Frame duration in 1/100th seconds (blank if 1 => 0.01 second):", 1); if (animationDuration < 1) { Console.WriteLine("Frame duration must be at least 1/100th second"); } Console.WriteLine(); } while (animationDuration < 1); int animationTicksPerSecond; do { animationTicksPerSecond = UserInputInt( $"Animation ticks per second (blank if {imageFrames.Length}/second):", imageFrames.Length); if (animationTicksPerSecond < 1) { Console.WriteLine("Ticks per second must be at least 1"); } Console.WriteLine(); } while (animationTicksPerSecond < 1); int quality; do { quality = UserInputInt("Render quality (blank if 100%):", 100); if (quality < 1 || quality > 100) { Console.WriteLine("Quality can not be less than 1% or more than 100% the original image frames"); } Console.WriteLine(); } while (quality < 1 || quality > 100); return(new GifData(animationDuration, animationTicksPerSecond, filename, imageFrames, GifDisposeMethod.Background, MagickColor.FromRgba(0, 0, 0, 0), outputDir, quality)); }
private void crop_images() { foreach (var s in sheet.sprites) { using (MagickImage image_a = new MagickImage(alphaPath)) { using (MagickImage image_rgb = new MagickImage(rgbPath)) { var g = new ImageMagick.MagickGeometry(s.x, s.y, s.w, s.h); image_a.Crop(g); image_rgb.Crop(g); image_rgb.Composite(image_a, CompositeOperator.CopyAlpha); int i = 1; while (i < Math.Max(s.w, s.h)) { i = i * 2; } image_rgb.Extent(new MagickGeometry(-(i / 2 - s.w / 2), -(i / 2 - s.h / 2), i, i), MagickColor.FromRgba(255, 255, 255, 0)); image_rgb.Write(folderPath + "/" + s.n); } } //return; } }
public void Execute() { MontageConfig montageConfig = Config.Montages; if (montageConfig == null) { throw new ConfigurationException("Montage action performed, but no montages are defined in the configuration."); } string font = montageConfig.Font ?? DefaultFontFamily(); MontageSettings montageSettings = new MontageSettings() { BackgroundColor = MagickColors.None, Geometry = new MagickGeometry(2, 2, 0, 0), TileGeometry = new MagickGeometry(8, 0), Font = font }; MagickReadSettings magickSettings = new MagickReadSettings() { FontFamily = font, FontPointsize = 14, BackgroundColor = MagickColors.None, FillColor = MagickColors.White }; foreach (PatternConfig pattern in montageConfig.Patterns) { string name = pattern.Name; DataResolver resolver = new DataResolver(pattern.Source); List <ResolvedData> resolverData = resolver.Data; if (resolverData.Count == 0) { throw new ConfigurationException($"The pattern for montage {name} doesn't match any files, exiting the application."); } resolverData.Sort(); using (MagickImageCollection collection = new MagickImageCollection()) { foreach (ResolvedData resolvedFile in resolverData) { string filename = resolvedFile.Name; string fileShortName = Path.GetFileNameWithoutExtension(filename); MagickImage magickImage = resolvedFile.ToMagickImage(magickSettings); magickImage.Extent(128, 144, MagickColors.None); MagickColor color = MagickColor.FromRgba(0, 0, 0, 88); DrawableRectangle drawableRect = new DrawableRectangle(0, 128, 144, 144); DrawableFillColor drawableColor = new DrawableFillColor(color); magickImage.Draw(drawableColor, drawableRect); magickImage.Annotate(fileShortName, Gravity.South); collection.Add(magickImage); Logger.Debug("Appended montage {0} with: {1}", name, resolvedFile); } Logger.Debug("Finished collecting input, creating a montage of {0} images.", collection.Count); using (IMagickImage montage = collection.Montage(montageSettings)) { string filepath = Path.Combine("build", "montages", name + ".png"); FileInfo outputPath = new FileInfo(filepath); outputPath.Directory?.Create(); Logger.Debug("Writing monatage with name {0} to {1}.", name, filepath); montage.Write(outputPath); } } } }
public static Geometry AutoAlign(Bitmap needle, Bitmap haystack, double retryThreshold = 1, int retryLimit = 10) { IntPoint[] harrisPoints1; IntPoint[] harrisPoints2; IntPoint[] correlationPoints1; IntPoint[] correlationPoints2; MatrixH homography; var mi1 = new MagickImage(needle); mi1.Equalize(); needle = mi1.ToBitmap(); var mi2 = new MagickImage(haystack); mi2.Equalize(); haystack = mi2.ToBitmap(); HarrisCornersDetector harris = new HarrisCornersDetector(0.04f, 20000f); harrisPoints1 = harris.ProcessImage(needle).ToArray(); harrisPoints2 = harris.ProcessImage(haystack).ToArray(); CorrelationMatching matcher = new CorrelationMatching(9, needle, haystack); IntPoint[][] matches = matcher.Match(harrisPoints1, harrisPoints2); correlationPoints1 = matches[0]; correlationPoints2 = matches[1]; RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.999); homography = ransac.Estimate(correlationPoints1, correlationPoints2); IntPoint[] inliers1 = correlationPoints1.Get(ransac.Inliers); IntPoint[] inliers2 = correlationPoints2.Get(ransac.Inliers); Concatenate concat = new Concatenate(needle); Bitmap img3 = concat.Apply(haystack); PairsMarker pairs = new PairsMarker( inliers1, inliers2.Apply(p => new IntPoint(p.X + needle.Width, p.Y))); var Image = pairs.Apply(img3); Image.Save(@"C:\AutoAlignDebug.png"); var pointCount = inliers1.Length; int[] xList1 = new int[pointCount]; int[] yList1 = new int[pointCount]; int[] xList2 = new int[pointCount]; int[] yList2 = new int[pointCount]; for (int n = 0; n < pointCount; n++) { xList1[n] = inliers1[n].X; yList1[n] = inliers1[n].Y; xList2[n] = inliers2[n].X; yList2[n] = inliers2[n].Y; } var f = new double[8] { xList1.Min(), yList1.Min(), xList1.Max(), yList1.Max(), xList2.Min(), yList2.Min(), xList2.Max(), yList2.Max() }; double distFromX1 = f[0] / needle.Width; double distFromX2 = f[2] / needle.Width; double leftRatio = f[0] / (f[2] - f[0]); double rightRatio = (needle.Width - f[2]) / (f[2] - f[0]); double distFromY1 = f[1] / needle.Height; double distFromY2 = f[3] / needle.Height; double topRatio = f[1] / (f[3] - f[1]); double bottomRatio = (needle.Height - f[3]) / (f[3] - f[1]); double leftDist = (f[6] - f[4]) * leftRatio; double rightDist = (f[6] - f[4]) * rightRatio; double topDist = (f[7] - f[5]) * topRatio; double bottomDist = (f[7] - f[5]) * bottomRatio; double x = f[4] - leftDist; double y = f[5] - topDist; double width = leftDist + (f[6] - f[4]) + rightDist; double height = topDist + (f[7] - f[5]) + bottomDist; mi1.Resize(new MagickGeometry((int)Math.Round(width), (int)Math.Round(height)) { IgnoreAspectRatio = true }); var mg = new MagickGeometry((int)Math.Round(x), (int)Math.Round(y), (int)Math.Round(width), (int)Math.Round(height)) { IgnoreAspectRatio = true }; mi2.Extent(mg, Gravity.Northwest, MagickColor.FromRgba(0, 0, 0, 0)); double delta = mi1.Compare(mi2, ErrorMetric.NormalizedCrossCorrelation); Geometry outGeo = new Geometry(x, y, width, height); if (delta < retryThreshold && retryLimit > 0) { retryLimit--; outGeo = AutoAlign(needle, haystack, delta, retryLimit); } return(outGeo); }
// Todo: Make into array returning task public static void Run3(Scan scan) { //Scanning = true; var deltas = new float[FEATURE_COUNT_LIMIT]; using (var fileImageBase = new MagickImage(scan.CurrentFrame.Bitmap)) { Parallel.ForEach(CompiledFeatures.CWatchZones, (CWatchZone) => { var thumbGeo = CWatchZone.MagickGeometry; using (var fileImageCropped = fileImageBase.Clone(CWatchZone.MagickGeometry)) { Parallel.ForEach(CWatchZone.CWatches, (CWatcher) => { fileImageCropped.ColorSpace = CWatcher.ColorSpace; // Can safely change since it doesn't directly affect pixel data. using (var fileImageComposed = GetComposedImage(fileImageCropped, CWatcher.Channel)) { if (CWatcher.Equalize) { fileImageComposed.Equalize(); } if (CWatcher.IsStandardCheck) { Parallel.ForEach(CWatcher.CWatchImages, (CWatchImage) => { using (var deltaImage = CWatchImage.MagickImage.Clone()) using (var fileImageCompare = fileImageComposed.Clone()) { if (CWatchImage.HasAlpha) { fileImageCompare.Composite(deltaImage, CompositeOperator.CopyAlpha); } var imageDelta = (float)deltaImage.Compare(fileImageCompare, CWatcher.ErrorMetric); deltas[CWatchImage.Index] = imageDelta; /* * if (CurrentIndex % 300 == 0 && CWatchImage.Index == 0) * { * fileImageCompare.Write(@"E:\test2.png"); * deltaImage.Write(@"E:\test3.png"); * fileImageComposed.Write(@"E:\test4.png"); * fileImageCropped.Write(@"E:\test5.png"); * fileImageBase.Write(@"E:\test6.png"); * } */ } }); } else if (CWatcher.IsDuplicateFrameCheck) { using (var deltaImagePre = new MagickImage((Bitmap)scan.PreviousFrame.Bitmap.Clone())) using (var fileImageCompare = (MagickImage)fileImageComposed.Clone()) { if (NeedExtent) { deltaImagePre.Extent(TrueCropGeometry.ToMagick(), Gravity.Northwest, MagickColor.FromRgba(0, 0, 0, 0)); } else { deltaImagePre.Crop(TrueCropGeometry.ToMagick(), Gravity.Northwest); } deltaImagePre.RePage(); deltaImagePre.Crop(thumbGeo, Gravity.Northwest); deltaImagePre.ColorSpace = CWatcher.ColorSpace; using (var deltaImage = GetComposedImage(deltaImagePre, CWatcher.Channel)) { if (CWatcher.Equalize) { fileImageCompare.Equalize(); } var imageDelta = (float)deltaImage.Compare(fileImageCompare, CWatcher.ErrorMetric); deltas[31] = imageDelta; } } } } }); } }); } Scanning = false; deltas[19] = 456.789F; Interlocked.Exchange(ref Program.floatArray, deltas); Interlocked.Exchange(ref Program.timeDelta, scan.TimeDelta); Interlocked.Increment(ref Program.count); scan.Clean(); }