public void DrawTransformed <TPixel>(TestImageProvider <TPixel> provider) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) using (var blend = Image.Load <TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) { AffineTransformBuilder builder = new AffineTransformBuilder() .AppendRotationDegrees(45F) .AppendScale(new SizeF(.25F, .25F)) .AppendTranslation(new PointF(10, 10)); // Apply a background color so we can see the translation. blend.Mutate(x => x.Transform(builder)); blend.Mutate(x => x.BackgroundColor(Color.HotPink)); // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); image.Mutate(x => x.DrawImage(blend, position, .75F)); image.DebugSave(provider, appendSourceFileOrDescription: false, appendPixelTypeToFileName: false); image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.002f), provider, appendSourceFileOrDescription: false, appendPixelTypeToFileName: false); } }
public override void DrawPoint(IImageProcessingContext context, float scale, PointF point) { float width = scale * Size.Width; float height = scale * Size.Height; float x = point.X - scale * Size.Width / 2; float y = point.Y - scale * Size.Height / 2; RectangleF rectangle = new RectangleF(x, y, width, height); if (Image != null) { PointF position = new PointF(Size.Width / 2, Size.Height / 2); AffineTransformBuilder affineTransformBuilder = new AffineTransformBuilder() .AppendScale(scale) .AppendTranslation(new PointF(rectangle.X, rectangle.Y)); //using (Image<Rgba32> tmpImage = Image.Clone()) //{ // tmpImage.Mutate(processing => // { // processing.Transform(affineTransformBuilder); // context.DrawImage(tmpImage, 1); // }); //} Image.Mutate(processing => { processing.Transform(affineTransformBuilder); context.DrawImage(Image, 1); }); } PointF[] points = rectangle.ToPoints(); DrawOutLine(context, scale, points.ToPath()); }
public static IImageProcessingContext Rotate(this IImageProcessingContext source, float degrees, Vector2 origin) { var affineBuilder = new AffineTransformBuilder(); affineBuilder.AppendRotationDegrees(degrees, origin); source.Transform(affineBuilder); return(source); }
private AffineTransformBuilder GetRotation() { Random random = new Random(); var builder = new AffineTransformBuilder(); var width = random.Next(10, Width); var height = random.Next(10, Height); var pointF = new PointF(width, height); var rotationDegrees = random.Next(0, MaxRotationDegrees); var result = builder.PrependRotationDegrees(rotationDegrees, pointF); return(result); }
public static Bitmap ComposeImage(Bitmap sourceImage, string descriptionText, float confidence, bool isOld, bool isBlackAndWhitePhoto, float expensiveMultiplier, bool isPainting, bool isSign, int?extractedYear, string extractedLocale, Random random) { Bitmap drawnBitmap = null; if (isPainting || isSign) { drawnBitmap = ImageTransforms.ComposeImageOntoPhoto(sourceImage); } else { drawnBitmap = sourceImage.Clone(); } PriceRange priceRange = GetPriceRange(descriptionText, confidence, expensiveMultiplier, random); int year = GetYear(drawnBitmap, isOld, isBlackAndWhitePhoto, extractedYear); string localePhrase = (extractedLocale != null ? (", " + extractedLocale) : ""); string fullCaption = descriptionText + String.Format(" (ca. {0}{1})\n ${2}-${3}", year, localePhrase, PriceRange.FormatPrice(priceRange.lowPrice), PriceRange.FormatPrice(priceRange.highPrice)); Bitmap footerImage = LoadImage(LoadImageType.Source, "footer.png"); float scale = (float)drawnBitmap.Width / (float)footerImage.Width; float footerHeight = scale * footerImage.Height; float footerOriginY = drawnBitmap.Height - footerHeight; float textOriginY = footerOriginY + 10.0f * scale; float textOriginX = 200.0f * scale; int fontSize = (int)(33 * scale); FontFamily family = GetCaptionFontFamily(); Font font = new Font(family, fontSize, FontStyle.Bold); TextGraphicsOptions textGraphicsOptions = new TextGraphicsOptions(); textGraphicsOptions.TextOptions.WrapTextWidth = drawnBitmap.Width - textOriginX - 10; AffineTransformBuilder footerTransformBuilder = new AffineTransformBuilder() .AppendScale(new SizeF(scale, scale)); footerImage.Mutate(x => x.Transform(footerTransformBuilder)); drawnBitmap.Mutate(x => x.DrawImage(footerImage, new SixLabors.ImageSharp.Point(0, (int)footerOriginY), new GraphicsOptions()) .DrawText(textGraphicsOptions, fullCaption, font, NamedColors.White, new PointF(textOriginX + 1, textOriginY + 1))); return(drawnBitmap); }
public static Bitmap ResizeToWithinAnalysisLimits(Bitmap originalImage) { if (IsWithinAnalysisLimits(originalImage)) { return(originalImage); } Bitmap scaledImage = originalImage.Clone(); float scale = (float)maxImageDimension / Math.Max(originalImage.Width, originalImage.Height); AffineTransformBuilder footerTransformBuilder = new AffineTransformBuilder().AppendScale(scale); scaledImage.Mutate(x => x.Transform(footerTransformBuilder)); return(scaledImage); }
public void ImageShouldDrawTransformedImage <TPixel>(TestImageProvider <TPixel> provider, PixelColorBlendingMode mode) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> image = provider.GetImage()) using (var blend = Image.Load <TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes)) { AffineTransformBuilder builder = new AffineTransformBuilder() .AppendRotationDegrees(45F) .AppendScale(new SizeF(.25F, .25F)) .AppendTranslation(new PointF(10, 10)); // Apply a background color so we can see the translation. blend.Mutate(x => x.Transform(builder).BackgroundColor(NamedColors <TPixel> .HotPink)); // Lets center the matrix so we can tell whether any cut-off issues we may have belong to the drawing processor var position = new Point((image.Width - blend.Width) / 2, (image.Height - blend.Height) / 2); image.Mutate(x => x.DrawImage(blend, position, mode, .75F)); image.DebugSave(provider, new[] { "Transformed" }); } }
/// <inheritdoc/> public override void DrawImage( OxyImage source, double srcX, double srcY, double srcWidth, double srcHeight, double destX, double destY, double destWidth, double destHeight, double opacity, bool interpolate) { if (source == null) { return; } var dest = new RectangleF((float)this.Convert(destX), (float)this.Convert(destY), (float)this.Convert(destWidth), (float)this.Convert(destHeight)); var src = new RectangleF((float)srcX, (float)srcY, (float)srcWidth, (float)srcHeight); var scale = new SizeF(dest.Width / src.Width, dest.Height / src.Height); // if we are outside the image, quit now if (dest.Right < 0 || dest.Left >= this.image.Width || dest.Bottom < 0 || dest.Top >= this.image.Height) { return; } // crop the bounds so that they are within the image bounds (this is necessary because we have to create a resized version of the cropped source image) var cropLeft = dest.Left < 0 ? -dest.Left : 0; var cropTop = dest.Top < 0 ? -dest.Top : 0; var cropRight = dest.Right >= this.image.Width ? dest.Right - this.image.Width : 0; var cropBottom = dest.Bottom >= this.image.Height ? dest.Bottom - this.image.Height : 0; dest = RectangleF.FromLTRB(dest.Left + cropLeft, dest.Top + cropTop, dest.Right - cropRight, dest.Bottom - cropBottom); src = RectangleF.FromLTRB(src.Left + (cropLeft / scale.Width), src.Top + (cropTop / scale.Height), src.Right - (cropRight / scale.Width), src.Bottom - (cropBottom / scale.Height)); var bytes = source.GetData(); var sourceImage = SixLabors.ImageSharp.Image.Load(bytes); var resampler = interpolate ? KnownResamplers.Triangle : KnownResamplers.NearestNeighbor; /* The idea now is to roughly crop the source before we resize and then precisely crop it, before drawing it onto the target * The steps required are: * - Crop the source image to -1/+2 pixel bounds (may need to increase these bounds depending on the resampler) * - Add a one pixel 'mirror' border, so that we can a clamped edge when interpolating * - Resize the source image by the appropriate scale with the appropriate resampler, simultaneously offseting by the non-integer parts of dest and src * - Crop to exactly what we want * - Draw the source image onto the destination image */ var doPad = interpolate; var srcRough = new Rectangle((int)Math.Floor(src.X), (int)Math.Floor(src.Y), (int)Math.Ceiling(src.Width + 3), (int)Math.Ceiling(src.Height + 3)); srcRough.Intersect(sourceImage.Bounds()); var srcOffset = new PointF(srcRough.X - src.X, srcRough.Y - src.Y); srcOffset.Offset(0.5f, 0.5f); // texel alignment for resampler if (doPad) { srcOffset.Offset(-1f, -1f); // offset from padding } var destOffset = new PointF(dest.X - (float)Math.Floor(dest.X), dest.Y - (float)Math.Floor(dest.Y)); var destRough = new Rectangle(0, 0, (int)Math.Ceiling(dest.Width), (int)Math.Ceiling(dest.Height)); var rescale = new AffineTransformBuilder().AppendTranslation(srcOffset).AppendScale(scale); try { sourceImage.Mutate(img => { img.Crop(srcRough); if (doPad) { img.Pad(srcRough.Width + 2, srcRough.Height + 2); } }); if (doPad) { sourceImage[0, 0] = sourceImage[1, 1]; sourceImage[sourceImage.Width - 1, 0] = sourceImage[sourceImage.Width - 2, 1]; sourceImage[0, sourceImage.Height - 1] = sourceImage[1, sourceImage.Height - 2]; sourceImage[sourceImage.Width - 1, sourceImage.Height - 1] = sourceImage[sourceImage.Width - 2, sourceImage.Height - 2]; for (int x = 1; x < sourceImage.Width - 1; x++) { sourceImage[x, 0] = sourceImage[x, 1]; sourceImage[x, sourceImage.Height - 1] = sourceImage[x, sourceImage.Height - 2]; } for (int y = 1; y < sourceImage.Height - 1; y++) { sourceImage[0, y] = sourceImage[1, y]; sourceImage[sourceImage.Width - 1, y] = sourceImage[sourceImage.Width - 2, y]; } } sourceImage.Mutate(img => { img.Transform(rescale, resampler); destRough.Intersect(sourceImage.Bounds()); img.Crop(destRough); }); this.Target.Mutate(img => { img.DrawImage(sourceImage, new Point((int)dest.X, (int)dest.Y), new GraphicsOptions(interpolate, (float)opacity)); }); } catch (ImageProcessingException) { // Swallow: it's probably because we are trying to render outside of the image: https://github.com/SixLabors/ImageSharp/pull/877 // TODO: verify that we are trying to render outside of the image... somehow // - I don't think this can be done without having to track the ImageSharp code unhealthily closely } finally { sourceImage.Dispose(); } }
private static void createTexture() { if (texturehandle >= 0) { GL.DeleteTexture(texturehandle); } texturehandle = GL.GenTexture(); atlas?.Dispose(); atlas = new Image <Rgba32>(1, 1, Color.Transparent); coordinates.Clear(); textures.Values.ToList().ForEach(x => { if (coordinates.ContainsKey(x.ID)) { return; } var _canvas = new Image <Rgba32>(Math.Max(atlas.Width, x.TextureImage.Width), atlas.Height + x.TextureImage.Height, Color.Transparent); var _transform = new AffineTransformBuilder().AppendTranslation(new PointF(0, atlas.Height)); var _texture = x.TextureImage.Clone(); _texture.Mutate(y => y.Flip(FlipMode.Vertical).Transform(_transform) ); _canvas.Mutate(y => y.DrawImage(atlas, 1).DrawImage(_texture, 1) ); coordinates.Add(x.ID, (new Vector2(0, atlas.Height), new Vector2(_texture.Width, _canvas.Height))); _texture.Dispose(); atlas.Dispose(); atlas = _canvas.Clone(); _canvas.Dispose(); }); // Create a byte array for OpenGL var _pixels = new List <byte>(4 * atlas.Width * atlas.Height); for (int y = 0; y < atlas.Height; y++) { for (int x = 0; x < atlas.Width; x++) { _pixels.Add(atlas[x, y].R); _pixels.Add(atlas[x, y].G); _pixels.Add(atlas[x, y].B); _pixels.Add(atlas[x, y].A); } } string _label = "atlas"; GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texturehandle); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, atlas.Width, atlas.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, _pixels.ToArray()); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); GL.ObjectLabel(ObjectLabelIdentifier.Texture, texturehandle, _label.Length, _label); }
public byte[] Generate(string text) { byte[] result; using (var imgText = new Image <Rgba32>(Width, Height)) { float position = 0; Random random = new Random(); byte startWith = (byte)random.Next(5, 10); imgText.Mutate(ctx => ctx.BackgroundColor(Color.Transparent)); FontFamily fontFamily = FontFamilies[random.Next(0, FontFamilies.Length)]; Font font = new Font(fontFamily, FontSize, FontStyle); foreach (char c in text) { var location = new PointF(startWith + position, random.Next(6, 13)); imgText.Mutate(ctx => ctx.DrawText(c.ToString(), font, TextColor[random.Next(0, TextColor.Length)], location)); position += TextMeasurer.Measure(c.ToString(), new RendererOptions(font, location)).Width; } AffineTransformBuilder rotation = GetRotation(); imgText.Mutate(ctx => ctx.Transform(rotation)); ushort size = (ushort)TextMeasurer.Measure(text, new RendererOptions(font)).Width; var img = new Image <Rgba32>(size + 10 + 5, Height); img.Mutate(ctx => ctx.BackgroundColor(Color.White)); Parallel.For(0, DrawLines, i => { int x0 = random.Next(0, random.Next(0, 30)); int y0 = random.Next(10, img.Height); int x1 = random.Next(img.Width / 2, img.Width); int y1 = random.Next(0, img.Height); img.Mutate(ctx => ctx.DrawLines(TextColor[random.Next(0, TextColor.Length)], GenerateNextFloat(MinLineThickness, MaxLineThickness), new PointF[] { new PointF(x0, y0), new PointF(x1, y1) }) ); }); img.Mutate(ctx => ctx.DrawImage(imgText, 0.80f)); Parallel.For(0, NoiseRate, i => { int x0 = random.Next(0, img.Width); int y0 = random.Next(0, img.Height); img.Mutate( ctx => ctx .DrawLines(NoiseRateColor[random.Next(0, NoiseRateColor.Length)], GenerateNextFloat(0.5, 1.5), new PointF[] { new Vector2(x0, y0), new Vector2(x0, y0) }) ); }); img.Mutate(x => { x.Resize(Width, Height); }); using (var ms = new MemoryStream()) { img.Save(ms, Encoder); result = ms.ToArray(); } } return(result); }
public byte[] Generate(string stringText) { byte[] result; using (var imgText = new Image <Rgba32>(_options.Width, _options.Height)) { float position = 0; Random random = new Random(); byte startWith = (byte)random.Next(5, 10); imgText.Mutate(ctx => ctx.BackgroundColor(Color.Transparent)); string fontName = _options.FontFamilies[random.Next(0, _options.FontFamilies.Length)]; Font font = SystemFonts.CreateFont(fontName, _options.FontSize, _options.FontStyle); foreach (char c in stringText) { var location = new PointF(startWith + position, random.Next(6, 13)); imgText.Mutate(ctx => ctx.DrawText(c.ToString(), font, _options.TextColor[random.Next(0, _options.TextColor.Length)], location)); position += TextMeasurer.Measure(c.ToString(), new RendererOptions(font, location)).Width; } //add rotation AffineTransformBuilder rotation = getRotation(); imgText.Mutate(ctx => ctx.Transform(rotation)); // add the dynamic image to original image ushort size = (ushort)TextMeasurer.Measure(stringText, new RendererOptions(font)).Width; var img = new Image <Rgba32>(size + 10 + 5, _options.Height); img.Mutate(ctx => ctx.BackgroundColor(Color.White)); Parallel.For(0, _options.DrawLines, i => { int x0 = random.Next(0, random.Next(0, 30)); int y0 = random.Next(10, img.Height); int x1 = random.Next(70, img.Width); int y1 = random.Next(0, img.Height); img.Mutate(ctx => ctx.DrawLines(_options.TextColor[random.Next(0, _options.TextColor.Length)], Extentions.GenerateNextFloat(_options.MinLineThickness, _options.MaxLineThickness), new PointF[] { new PointF(x0, y0), new PointF(x1, y1) }) ); }); img.Mutate(ctx => ctx.DrawImage(imgText, 0.80f)); Parallel.For(0, _options.NoiseRate, i => { int x0 = random.Next(0, img.Width); int y0 = random.Next(0, img.Height); img.Mutate( ctx => ctx .DrawLines(_options.NoiseRateColor[random.Next(0, _options.NoiseRateColor.Length)], Extentions.GenerateNextFloat(0.5, 1.5), new PointF[] { new Vector2(x0, y0), new Vector2(x0, y0) }) ); }); img.Mutate(x => { x.Resize(_options.Width, _options.Height); }); using (var ms = new MemoryStream()) { img.Save(ms, _options.Encoder); result = ms.ToArray(); } } return(result); }