How can I get the object of effect-applied source - c#

I applied customized pixel-shader effect to an image.
var eff = new Shaders.PixelateEffect();
eff.HorizontalPixelCounts = 15;
eff.VerticalPixelCounts = 15;
IMG1.Effect = eff;
Then I tried to merge and overlay between the effect applied image(IMG1) and another image.(IMG2)
But, IMG1.Source bring me an original image.
ImageUtils.OverlayingImages(IMG1.Source, IMG2.Source, x, y);
How can I get an updated image source?
it happened same when I rotate the image.
Do I need to capture the image with RenderTargetBitmap?
Thank you in advance.

I've solved it like this with RenderTargetBitmap. anyway, thank you for the comments.
var eff = new Shaders.PixelateEffect();
eff.HorizontalPixelCounts = 15;
eff.VerticalPixelCounts = 15;
BitmapSource bitmap = (BitmapSource)IMG1.Source;
var r = new Rectangle();
r.Fill = new ImageBrush(bitmap);
r.Effect = eff;
Size sz = new Size(bitmap.PixelWidth, bitmap.PixelHeight);
r.Measure(sz);
r.Arrange(new Rect(sz));
var rtb = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight, 96, 96
, PixelFormats.Default);
rtb.Render(r);
// here's the updated source with the custom effect.
IMG1.Source= ImageUtils.RenderTargetBitmapToBitmap(rtb);

Related

Oxyplot annotation with brush

I wish to colour my OxyPlot's RectangleAnnotation with something more pretty than just a plain colour, i.e. some type of brush (GradientBrush etc.). I am working in WPF.
This question (PlotAreaBackground can be defined using gradient ?) on their GitHub site suggests that an annotation can be given a gradient, but I cannot find the suggested example.
Is there a way of applying a brush to a RectangleAnnotation? or any other way of creating coloured areas on a graph that are linked to the values on the axis?
I think that this is the suggested example.
I've modified it to look like a rectangle annotation, because the example fills the entire background. Hope it helps.
Efect:
Code:
// create a gradient image of height n
int n = 256;
var imageData1 = new OxyColor[n, 1];
for (int i = 0; i < n; i++)
{
imageData1[i, 0] = OxyColor.Interpolate(OxyColors.Red, OxyColors.Blue, i / (n - 1.0));
}
PngBitmapEncoder encoder = new PngBitmapEncoder();
PngEncoder encode = new PngEncoder(new PngEncoderOptions());
var image1 = new OxyImage(encode.Encode(imageData1));
ImageAnnotation anotation = new ImageAnnotation
{
ImageSource = image1,
Interpolate = true,
Layer = AnnotationLayer.BelowAxes,
X = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
Y = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
Width = new PlotLength(0.1, PlotLengthUnit.RelativeToPlotArea),
Height = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top
};
plotModel.Annotations.Add(anotation);

Blur effect on image: different result before and after saving

I have a bug in my image editor with the blur tool.
When I select the rectangle to set the blur effect, and when I apply, result is a bit different see:
To create the "Before" I do:
var blurredImage = ExtractImageToBlur(); // extract the selected area from image
BlurredImageRectangle.Fill = new ImageBrush(blurredImage);
var effect = new BlurEffect();
effect.KernelType = KernelType.Gaussian;
effect.RenderingBias = RenderingBias.Quality;
effect.Radius = m_blurValue;
BlurredImageRectangle.Effect = effect;
To create the "After", I do:
var blurredImage = ExtractImageToBlur(); // extract the selected area from image
Rectangle rectangleToRender = new Rectangle();
rectangleToRender.Fill = new ImageBrush(blurredImage);
var effect = new BlurEffect();
effect.KernelType = KernelType.Gaussian;
effect.RenderingBias = RenderingBias.Quality;
effect.Radius = m_blurValue;
rectangleToRender.Effect = effect;
Size size = new Size(croppedImg.PixelWidth, croppedImg.PixelHeight);
rectangleToRender.Measure(size);
rectangleToRender.Arrange(new Rect(size));
var render = new RenderTargetBitmap(croppedImg.PixelWidth, croppedImg.PixelHeight, 96, 96, PixelFormats.Pbgra32);
render.Render(rectangleToRender);
// Merge the source with the blurred section
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext context = drawingVisual.RenderOpen())
{
int left = (int)(Canvas.GetLeft(BlurredImageRectangle) * WidthRatio);
int top = (int)(Canvas.GetTop(BlurredImageRectangle) * HeightRatio);
context.DrawImage(Source, new Rect(0, 0, Source.PixelWidth, Source.PixelHeight));
context.DrawImage(render, new Rect(left, top, croppedImg.PixelWidth, croppedImg.PixelHeight));
}
var bitmap = new RenderTargetBitmap(Source.PixelWidth, Source.PixelHeight, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(drawingVisual);
And when I play with the blur radius, its sometimes a lot more different from both images.
Why its not the same?
Found the problem.
When I was drawing the rectangle on the screen, I applied the blur effect on the pixels on the screen.
When I hit save, the blur effect is applied on the pixel on the image on disk.
Huge difference.

WriteableBitmap Doesn't change pixel color in wpf

I use WriteableBitmap to set pixel in Wpf. but when I used writePixels method to change the color of pixels it's change color to black :(. It's my code snap:
ofdOpen.ShowDialog();
BitmapImage img = new BitmapImage(new Uri(ofdOpen.FileName));
WriteableBitmap wbmap = new
WriteableBitmap(img);
byte[] pixels = new byte[
wbmap.PixelHeight*wbmap.PixelWidth*
wbmap.Format.BitsPerPixel/8];
pixels[0] =255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
wbmap.WritePixels(
new Int32Rect(0, 0,
wbmap.PixelWidth, wbmap.PixelHeight),
pixels,
wbmap.PixelWidth * wbmap.
Format.BitsPerPixel / 8, 0);
image1.Source = wbmap;
I'm googling too much. but I couldn't find any source about this problem.
It's appearing black because you're rewriting the entire contents of the image, not just a few pixels. Your pixels array is declared to be to be the size of the entire image, but you are only setting two of the first four bytes of color data. So, when you call WritePixels, it's redrawing the entire image with the provider color data, which is almost all 0's.
To correct this, only declare the pixels array to be the size of the pixels you want to write.
Finllay I found solution:
BitmapImage originalIamge = new BitmapImage();
originalIamge.BeginInit();
originalIamge.UriSource = new Uri(ofdOpen.FileName);
originalIamge.EndInit();
BitmapSource bitmapSource = new FormatConvertedBitmap(originalIamge, PixelFormats.Bgr32, null, 0);
wbmap = new WriteableBitmap(bitmapSource);
h = wbmap.PixelHeight;
w = wbmap.PixelWidth;
pixelData = new int[w * h];
widthInByte = 4 * w;
wbmap.CopyPixels(pixelData, widthInByte, 0);
image1.Source = wbmap;
Point absoluteScreenPos = PointToScreen(Mouse.GetPosition((IInputElement)sender));
Image img = new Image();
BitmapImage point = new BitmapImage(
new Uri("Images/Dott.png",
UriKind.Relative));
img.Source = point;
var rt = ((UIElement)image1).RenderTransform;
var offsetX = rt.Value.OffsetX;
var offsetY = rt.Value.OffsetY;
int newX = (int)Mouse.GetPosition((IInputElement)sender).X;
int newY = (int)Mouse.GetPosition((IInputElement)sender).Y;
for (int i = 0; i < 400; i++)
{
pixelData[i] = 0x000000ff;
}
wbmap.WritePixels(new Int32Rect(newX,newY,10,10), pixelData, widthInByte, 0);
image1.Source = wbmap;

WriteableBitmap.SaveJpeg renders a black image (WP7)

I'm trying to render some text and an image to a writeable bitmap to make 1 larger image, and this method has worked in other locations for creating or manipulating images, but for some reason, this instance is only creating a black image. If I just set the image source to the original WriteableBitmap, it shows just fine, but when I call SaveJpeg and then LoadJpeg, it shows as a black image (and yes, I need to call SaveJpeg since this is actually getting passed up to a server). The following is how I'm trying to render the elements:
NoteViewModel note = Instance.Note;
var grid = new Grid()
{
Height = 929,
Width = 929
};
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(679) });
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
var noteText = new TextBlock()
{
Text = note.Text,
FontFamily = note.FontFamily,
Foreground = note.FontColor,
TextWrapping = System.Windows.TextWrapping.Wrap,
Width = 929,
Height = 679
};
Grid.SetRow(noteText, 0);
grid.Children.Add(noteText);
WriteableBitmap sigImage = Instance.Signature.SignatureImage;
var sig = new Image()
{
Source = sigImage,
Height = 250,
Width = (sigImage.PixelWidth / sigImage.PixelHeight) * 250,
Margin = new Thickness(929 - ((sigImage.PixelWidth / sigImage.PixelHeight) * 250), 0, 0, 0)
};
Grid.SetRow(sig, 1);
grid.Children.Add(sig);
var messagePicture = new WriteableBitmap(grid, null);
var stream = new MemoryStream();
messagePicture.SaveJpeg(stream, messagePicture.PixelWidth, messagePicture.PixelHeight, 0, 100); //Save to a temp stream
stream.Position = 0;
var test = new WriteableBitmap(929,929); //Load the picture back up to see it
test.LoadJpeg(stream);
img.Source = test; //Show the image on screen (img is an Image element)
So apparently WriteableBitmap will render a transparent background as black when calling SaveJpeg, so I solved this by rendering a white canvas as well, like so:
var background = new Canvas()
{
Width = 929,
Height = 929,
Background = new SolidColorBrush(Colors.White)
};
messagePicture.Render(background, new TranslateTransform());

How do I print an Image from a Uri?

I am attempting to print a JPEG file that I reference using a Uri object and am having some difficulties. I found that while the image was printing, it was cropped slightly and was flipped and mirrored. I'm guessing that the crop was caused by a size not being set properly but have no idea why it's being flipped and rotated. Assuming that this was a natural oddity, I attempted to resolve the issue by applying a transform to the drawingContext object but this results a blank page being printed. Here is my code:
public void Print(List<Uri> ListToBePrinted)
{
XpsDocumentWriter writer =
PrintQueue.CreateXpsDocumentWriter(this.SelectedPrinter.PrintQueue);
PrintCapabilities printerCapabilities =
this.SelectedPrinter.PrintQueue.GetPrintCapabilities();
Size PageSize =
new Size(printerCapabilities.PageImageableArea.ExtentWidth,
printerCapabilities.PageImageableArea.ExtentHeight);
foreach (Uri aUri in ListToBePrinted)
{
BitmapImage anImage = new BitmapImage(aUri);
//create new visual which would be initialized by image
DrawingVisual drawingVisual = new DrawingVisual();
//create a drawing context so that image can be rendered to print
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Flips along X and Y axis (flips and mirrors)
drawingContext.PushTransform(new ScaleTransform(-1, -1));
drawingContext.DrawImage(anImage, new Rect(PageSize));
drawingContext.Close();
writer.Write(drawingVisual);
}
}
Any help would be greatly appreciated - thank you!
Here's what I ended up with:
public void Print(List<Uri> ListToBePrinted)
{
XpsDocumentWriter writer =
PrintQueue.CreateXpsDocumentWriter(this.SelectedPrinter.PrintQueue);
PrintCapabilities printerCapabilities =
this.SelectedPrinter.PrintQueue.GetPrintCapabilities();
Size PrintableImageSize =
new Size(printerCapabilities.PageImageableArea.ExtentWidth,
printerCapabilities.PageImageableArea.ExtentHeight);
foreach (Uri aUri in ListToBePrinted)
{
DrawingVisual drawVisual = new DrawingVisual();
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(aUri);
imageBrush.Stretch = Stretch.Fill;
imageBrush.TileMode = TileMode.None;
imageBrush.AlignmentX = AlignmentX.Center;
imageBrush.AlignmentY = AlignmentY.Center;
using (DrawingContext drawingContext = drawVisual.RenderOpen())
{
// Flips along X and Y axis (flips and mirrors)
drawingContext.PushTransform(new ScaleTransform(-1, 1, PrintableImageSize.Width / 2, PrintableImageSize.Height / 2));
drawingContext.PushTransform(new RotateTransform(180, PrintableImageSize.Width / 2, PrintableImageSize.Height / 2)); // Rotates 180 degree
drawingContext.DrawRectangle(imageBrush, null, new Rect(25, -25, PrintableImageSize.Width, PrintableImageSize.Height));
}
writer.Write(drawVisual);
}
}
The image is a little fuzzy but is certainly acceptable. I'm still not sure why my image needed to be flipped or mirrored.
Could you do something like:
BitmapImage anImage = new BitmapImage(aUri);
Image image = new Image();
image.BeginInit();
image.Source = anImage;
image.EndInit();
image.Measure(PageSize);
image.InvalidateVisual();
Then just print the Image object since it derives from Visual...
You need to call InvalidateVisual so that OnRender will be called, if you didn't it would result in a blank image...

Categories

Resources