I'm using the Svg.Core library (version 3.0.49.2) to render SVGs (defined in strings) to PNG images. No matter what I do, any shape seems to be rendered with a black stroke and a black fill.
Here's the code I'm using for a simple rectangle, as an example:
var svgString = #"<svg width=""300"" height=""300"" xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink""><rect x=""5"" y=""5"" height=""90"" width=""50"" fill=""#ef0000"" stroke=""#00ef00"" /></svg>";
var svgDocument = SvgDocument.FromSvg<SvgDocument>(svgString);
var bitmap = svgDocument.Draw();
bitmap.Save(fileName, ImageFormat.Png);
which ends up rendering a rectangle of the correct height and width, but all black:
I've seen a number of posts that mention various versions of inlining styles, but regardless of whether I'm using a style="" approach or a fill="", the problem continues. Also seems to happen without fill color specified or using standard color names instead of RGB values.
Any help or ideas are appreciated!
The best answer I have come up with here is from the comment earlier. If you put the following around it: svgDoc.Color = new SvgColourServer(Color.DarkGreen); svgDoc.StopColor = new SvgColourServer(Color.DarkGreen); svgDoc.Stroke = new SvgColourServer(Color.DarkGreen); svgDoc.Fill = new SvgColourServer(Color.DarkGreen); , you will get colors in the SVG. Posting this as the answer in case anyone runs into this issue down the road.
Related
I'm actually trying to add some text to an image in C# with
System.Windows.Forms.TextRenderer.DrawText(Graphics, string, Rectangle, Color, TextFormaFlags)
I prepare my image (which is a png) by loading it in memory, with something similar to
Image image = ImageCache.Get(...);
bitmap = new Bitmap(image);
graphic = Graphics.FromImage(bitmap);
I then draw my text with the above command. The problem is that whatever I use for the color, even something like
System.Drawing.Color.FromArgb(0,255,255,255)
the transparency is not drawn. I tried many settings for
graphics.TextRenderingHint
and different combinations of fonts, transparency level, etc. Is there something I don't understand here? Any hint is appreciated.
Thank you.
As mentionned in the comments : if you try to draw transparent text with
System.Windows.Forms.TextRenderer.DrawText
because you look for the advantages brought by GDI in C#, you just can't. Use
System.Drawing.Graphics.DrawString
instead, even if the result for the word-wrapping is slightly inferior with GDI+.
I got some weird issues when resizing an image with transparency in Magick.NET. I am using Q16-AnyCPU.
I am resizing a 100px image to 400px.
MagickImage image = new MagickImage("test.png");
image.Resize(400, 400);
image.Write("test_resized.png");
I have tried many combinations of image.FilterType and image.Interpolate without any good results.
Only when I use image.AdaptiveResize(400, 400);, it looks somewhat better, but not as expected. The final image I want to resize is much bigger and AdaptiveResize is very slow.
When I disable Alpha via image.Alpha(AlphaOption.Off); I looks quice nice, but I want to keep the alpha.
Source image (the white area is transparent):
What I get:
What I want:
I had to set VirtuaPixelMethod, thanks for the hint:
MagickImage image = new MagickImage("test.png");
image.VirtualPixelMethod = VirtualPixelMethod.Transparent;
image.Resize(400, 400);
image.Write("test_resized.png");
This has become a serious blocker for a program I'm working on to manipulate images that have Alpha channels.
Many of the images I have contain color information where an Alpha channel is completely transparent, and yet as soon as I try to load them into System.Drawing.Graphics, it changes anything with of Alpha of 0, into Black with an Alpha of 0.
Here is a basic sample of the issue.
I have looked around trying to find a reason, answer, or workaround, but I haven't found anything that even alludes to this issue.
Any help would be appreciated at this point.
var myTestTransparentColor = Color.FromArgb(0, 255, 128, 64);
var image = new Bitmap(135, 135, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(image))
{
g.Clear(myTestTransparentColor);
}
var color = image.GetPixel(0, 0);
Debug.Assert(color == myTestTransparentColor, "channels must match original");
EDIT:
After further testing I don't really see a way ahead by using System.Drawing.Graphics, so my only solution which is not really an answer, is to avoid System.Drawing.Graphics entirely. Looking through my code, it looks like I can avoid it.
Its just after years of using System.Drawing.Graphics for drawing shapes, planting text over images, I find it irritating for System.Drawing.Graphics to have a significant drawback like this.
I still would like to know if I can use System.Drawing.Graphics and keep my ARGB intact, but I guess I can live without it for now.
I think Vincent Povirk has answered my question appropriately here: Drawing PixelFormat32bppPARGB images with GDI+ uses conventional formula instead of premultiplied one
"The format of your foreground image doesn't matter (given that it has alpha) because you're setting it to a Gdiplus::Color. Color values are defined as non-premultiplied, so gdiplus multiplies the components by the alpha value when it clears the foreground image. The alternative would be for Color values to have different meaning depending on the format of the render target, and that way lies madness."
"If you really want this level of control over the rendering, you'll have to lock the bitmap bits and do it yourself."
So, I am doing it myself.
I'm using Steema TeeChart v4.1.2010.11303. I want to export a chart to a PNG image with a transparent background.
The resulting image has "distorted" or bold text in the left and bottom axis and in the header. It looks like being rendered with a raster font with a too low resolution. The legend on the right on the other hand looks fine:
The following sample code can be used to reproduce the problem:
TChart tChart = new TChart();
tChart.Aspect.View3D = false;
tChart.Panel.Brush.Gradient.Visible = false;
// Make the background of the chart transparent.
tChart.Panel.Transparent = true;
Steema.TeeChart.Styles.Bar series1 = new Steema.TeeChart.Styles.Bar( tChart.Chart );
series1.FillSampleValues();
tChart.Draw();
tChart.Graphics3D.BufferStyle = Steema.TeeChart.Drawing.BufferStyle.None;
using ( System.IO.Stream stream = new System.IO.MemoryStream() )
{
tChart.Export.Image.PNG.Width = m_PictureBox.Width;
tChart.Export.Image.PNG.Height = m_PictureBox.Height;
tChart.Export.Image.PNG.Save( stream );
// Show the bitmap in a Windows Forms PictureBox.
// Alternatively, it can also be saved in a file, which makes no difference.
PictureBox.Image = new Bitmap( stream );
}
When switching off the transparency with tChart.Panel.Transparent = false;, all text looks fine. However, I need a transparent background.
Is this a bug in TeeChart or am I missing something?
It is a know behavior for us and we haven't found a good solution for this problem, for the moment. If we will find a solution that we consider correct or we will arrive an interesting conclusion about problem of png export, we will inform you immediatly.
Thanks.
Best Regard,
Sandra Pazos
I am trying to draw two images side-by-side using the C# Drawing namespace.
Here is a very simple example that assumes we have two images of the same height:
Image[] oldImages = GetOldImages();
var newImage = new Bitmap(oldImages[0].Width + oldImages[1].Width, 800);
using (var newImageGraphics = Graphics.FromImage(newImage))
{
newImageGraphics.DrawImage(oldImages[0], 0, 0);
newImageGraphics.DrawImage(oldImages[1], oldImage[0].Width, 0);
newImageGraphics.Save();
}
This works OK if the resolution of the two old images are the same.
However, if the resolutions are different then the image is resized, causing problems. For example, if the first image has a different resolution, then the second image will be positioned incorrectly.
Does anyone know how I can fix this problem easily? Ideally I want the original image's height and width to remain the same when they are drawn on to the new image.
Try this trick:
Bitmap picture_1 = new Bitmap(picture_1_path);
Graphics graphics = Graphics.FromImage(picture_1);
Bitmap picture_2 = new Bitmap(picture_2_path);
picture_2.SetResolution(graphics.DpiX, graphics.DpiY);
//Then do with pictures anything
Basically you'll need to resize the second image before adding to the new image.
Though as you say you want to retain the original height and width you'll need to change the canvas size of the second image. This increases the size of the image by adding empty space around the actual image. If the second image is larger than the first you'll need to do this to the first image instead.