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);
Related
I'm generating barcodes using ZXing.NET with this code
BarcodeWriter barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat,
Options = new EncodingOptions
{
Width = barCodeWidth,
Height = barCodeHeight,
PureBarcode = !GenerateBarCodeWithText
}
};
Bitmap barCodeBitmap = barcodeWriter.Write(content);
So currently each barcode (and with text) is just black. Is there a way I can pass in a Color object to colorize the barcode and text red for example? I tried this hacky solution to get the current pixel color, check if it's white and if not, colorize it to the specified font color.
for (int x = 0; x < barCodeBitmap.Width; x++)
{
for (int y = 0; y < barCodeBitmap.Height; y++)
{
Color currentColor = barCodeBitmap.GetPixel(x, y);
bool isWhite = currentColor == Color.White;
if (!isWhite) // this pixel should get a new color
{
barCodeBitmap.SetPixel(x, y, fontColor); // set a new color
}
}
}
Unfortunately each pixel gets colorized..
For colorizing the whole code (including the text) you can use the following snippet:
BarcodeWriter barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat,
Options = new EncodingOptions
{
Width = barCodeWidth,
Height = barCodeHeight,
PureBarcode = !GenerateBarCodeWithText
},
Renderer = new BitmapRenderer
{
Foreground = Color.Red
}
};
Bitmap barCodeBitmap = barcodeWriter.Write(content);
If you want different colors for the barcode and the text you have to write your own renderer implementation and use this instead of the BitmapRenderer.
You can take a look at the sources of BitmapRenderer and use it as a template for your own implementation:
https://github.com/micjahn/ZXing.Net/blob/master/Source/lib/renderer/BitmapRenderer.cs
Add a new property "TextColor" for example and use it in the line
var brush = new SolidBrush(Foreground);
changed to
var brush = new SolidBrush(TextColor);
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);
I have 4 float points (positions in 2D) and I want to draw and fill a polygon (with vertices at those 4 positions) in 2D.
How can I do that with sharpdx?
I have found how to draw and fill a polygon. I have used drawGeometry and fillGeometry methods of RenderTarget object.
I wont mention how to initialize the directx
PathGeometry geo1;
GeometrySink sink1;
FactoryD2D factory = new FactoryD2D();
var dpi = factory.DesktopDpi;
RenderTarget renderTarget;
renderTarget = new RenderTarget(factory, backBuffer, new RenderTargetProperties()
{
DpiX = dpi.Width,
DpiY = dpi.Height,
MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_DEFAULT,
PixelFormat = new SharpDX.Direct2D1.PixelFormat(Format.Unknown, AlphaMode.Ignore),
Type = RenderTargetType.Hardware,
Usage = RenderTargetUsage.None
});
// and after all initialization
pta[0] = new SharpDX.Vector2(pts[4].X, pts[4].Y);
pta[1] = new SharpDX.Vector2(pts[5].X, pts[5].Y);
pta[2] = new SharpDX.Vector2(pts[6].X, pts[6].Y);
pta[3] = new SharpDX.Vector2(pts[7].X, pts[7].Y);
geo1 = new PathGeometry(factory);
sink1 = geo1.Open();
sink1.BeginFigure(pta[0], new FigureBegin());
sink1.AddLines(new SharpDX.Vector2[] { pta[1], pta[2], pta[3] });
sink1.EndFigure(new FigureEnd());
sink1.Close();
Color penColor = Color.Black;
SolidColorBrush penBrush = new SolidColorBrush(g, new SharpDX.Color(penColor.R, penColor.G, penColor.B));
Color color = AddColor(pt, zmin, zmax);
SolidColorBrush aBrush = new SolidColorBrush(g, new SharpDX.Color(color.R, color.G, color.B));
renderTarget.DrawGeometry(geo1, penBrush);
renderTarget.FillGeometry(geo1, aBrush);
geo1.Dispose();
sink1.Dispose();
You can add other geos and sinks in order to add more shapes on to it
Hope this help to somebody who is lost and trying to find an answer desperately like me
I have a uniform grid that has rectangles dynamically added to it. I want to remove a particular rectangle, but I am getting the following error when trying to pass it to the Remove method:
Cannot convert from 'System.Drawing.Rectangle' to 'System.Windows.UIElement'
My code is:
Rectangle swatch = (Rectangle)ug_Thumbnails.FindName("s_" + _instance);
ug_Thumbnails.Children.Remove(swatch);
I tried casting, and got an error saying that you couldn't do it.
EDIT: Per request, here's the code to create the rectangle:
System.Windows.Shapes.Rectangle swatch = new System.Windows.Shapes.Rectangle();
swatch.Width = 50;
swatch.Height = 50;
swatch.Margin = new Thickness(0, 5, 5, 0);
swatch.StrokeThickness = 1;
swatch.Stroke = System.Windows.Media.Brushes.Gray;
swatch.Name = "s_" + name.ToString();
double groupsize = 100 / colors.Count();
DrawingBrush blackBrush = new DrawingBrush();
DrawingGroup checkersDrawingGroup = new DrawingGroup();
List<SolidColorBrush> brushes = colors;
double location = 0;
for (int i = 0; i < colors.Count(); i++)
{
GeometryDrawing drawing = new GeometryDrawing(brushes[i], null,
new RectangleGeometry(new Rect(location, 0, groupsize, groupsize)));
checkersDrawingGroup.Children.Add(drawing);
location += groupsize;
}
blackBrush.Drawing = checkersDrawingGroup;
swatch.Fill = blackBrush;
swatch.MouseUp += new MouseButtonEventHandler(loadSwatchResources);
ug_Thumbnails.Children.Add(swatch);
You need to use the Rectangle in System.Windows.Shapes when trying to reference a rectangle in WPF. This is specifically for rectangles in WPF and as such is a bit different than the System.Drawing rectangle class. You should be able to cast to this version of rectangle since it derives from FrameworkElement. See http://msdn.microsoft.com/en-us/library/system.windows.shapes.rectangle(v=vs.110).aspx for more info.
I have encountered a very odd problem today using WPF. Here is the code I have used to draw 10000 LineGeometry objects.
// Draw 10000 lines
var g = new GeometryGroup();
var x = 0;
var y = 0;
var n = 1;
while (n < 10000)
{
x = x + 20;
if (x > 600)
{
x = 0;
y = y + 20;
}
var l = new LineGeometry
{
StartPoint = new Point(x, y),
EndPoint = new Point(x, y + 15)
};
g.Children.Add(l);
n++;
}
var drawing = new GeometryDrawing {Geometry = g};
var drawingGroup = new DrawingGroup();
drawingGroup.Children.Add(drawing);
var myPen = new Pen {Thickness = 1, Brush = Brushes.Yellow};
drawing.Pen = myPen;
var myImage = new Image {Stretch = Stretch.None, Margin = new Thickness(10)};
var myDrawingImage = new DrawingImage {Drawing = drawingGroup};
myImage.Source = myDrawingImage;
canvas.Children.Add(myImage);
Now as you can see the result is not crisp and I used the code below to achieve better results.
RenderOptions.SetEdgeMode(myImage, EdgeMode.Aliased);
The image gets crisp but has another side effects as you can see in the image below.
Some lines are now shown.
Some extra odd lines are shown.
I have included the full code so you can experiment this for yourself.
Note:
I'm using ZoomBorder class around the Canvas canvas.
Pan & Zoom Image
Have you tried using
RenderOptions.SetBitmapScalingMode(myImage, BitmapScalingMode.HighQuality);
instead?
You can also set it on your Canvas control as well..
<Canvas RenderOptions.BitmapScalingMode="HighQuality"> ...
This is not a real answer but I want add something to that odd behavior of WPF in hope somebody can come up with a real explanation.
I added a single line from (0,0)-(20000,20000). Creating 8000 line objects (n < 8000) produces the expected result like this:
Now, creating 9000 line objects will totally mess it up, but see for yourself:
Without setting EdgeMode.Aliased it looks fine, even with high counts of objects.