如何将Geometry
保存为图像?
例如,我有List<Geometry>
。
我希望它如下:
for (int i = 0; i < GeometryList.Count; i++)
{
Pen TestPen = new Pen(Brushes.Black, 1);
GeometryDrawing TestDrawing = new GeometryDrawing(Brushes.Black, TestPen, TestGeometry);
Bitmap b = TestDrawing as Bitmap;
b.Save(System.AppDomain.CurrentDomain.BaseDirectory + i + ".png", ImageFormat.Png);
}
更新
我几个小时前写的代码:
private void CreateFontMap(string PathTofont)
{
GlyphTypeface font = new GlyphTypeface(new Uri(PathTofont));
List<ushort> fontNum = new List<ushort>();
foreach (KeyValuePair<int, ushort> kvp in font.CharacterToGlyphMap)
{
fontNum.Add(kvp.Value);
}
if (fontNum.Count > 0)
{
int mapWidth = 50 * 20;
int mapHeight = 50 * (getRowNum(fontNum.Count + 1) + 1);
Bitmap b = new Bitmap(mapWidth, mapHeight);
Graphics g = Graphics.FromImage(b);
System.Windows.Media.Pen glyphPen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Red, 1);
Geometry glyphGeometry;
for (int i = 0; i < fontNum.Count; i++)
{
glyphGeometry = font.GetGlyphOutline(fontNum[i], 50, 1);
RenderTargetBitmap bmp = new RenderTargetBitmap(50, 50, 96, 96, PixelFormats.Pbgra32);
DrawingVisual viz = new DrawingVisual();
DrawingContext dc = viz.RenderOpen();
dc.DrawGeometry(System.Windows.Media.Brushes.Red, null, glyphGeometry);
dc.Close();
bmp.Render(viz);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
MemoryStream myStream = new MemoryStream();
encoder.Save(myStream);
int rowNum = (getRowNum(i));
g.DrawImage(System.Drawing.Bitmap.FromStream(myStream), new PointF((i - rowNum * 20) * 50, rowNum * 50));
}
g.Dispose();
b.Save(System.AppDomain.CurrentDomain.BaseDirectory + "map.png", ImageFormat.Png);
b.Dispose();
}
}
private int getRowNum(int p)
{
return p / 20;
}
但我得Img2而不是。
更新2: 我改变了这个:
DrawingVisual viz = new DrawingVisual();
DrawingContext dc = viz.RenderOpen();
dc.DrawGeometry(System.Windows.Media.Brushes.Red, null, glyphGeometry);
dc.Close();
为:
DrawingVisual viz = new DrawingVisual();
DrawingContext dc = viz.RenderOpen();
dc.DrawImage(geometryImage, new Rect(0, 0, 50, 50));
dc.Close();
并补充说:
glyphDrawing = new GeometryDrawing(System.Windows.Media.Brushes.Black, glyphPen, glyphGeometry);
DrawingImage geometryImage = new DrawingImage(glyphDrawing);
geometryImage.Freeze();
img1.Source = geometryImage;
一切正常。
答案 0 :(得分:2)
对于想要以固定大小居中呈现几何体的任何人,这是执行此操作的代码:
const int TargetSize = 14;
private static void Save(Geometry geometry, string fileName)
{
var rect = geometry.GetRenderBounds(new Pen(Brushes.Black, 0));
var bigger = rect.Width > rect.Height ? rect.Width : rect.Height;
var scale = TargetSize / bigger;
Geometry scaledGeometry = Geometry.Combine(geometry, geometry, GeometryCombineMode.Intersect, new ScaleTransform(scale, scale));
rect = scaledGeometry.GetRenderBounds(new Pen(Brushes.Black, 0));
Geometry transformedGeometry = Geometry.Combine(scaledGeometry, scaledGeometry, GeometryCombineMode.Intersect, new TranslateTransform(((TargetSize - rect.Width) / 2) - rect.Left, ((TargetSize - rect.Height) / 2) - rect.Top));
RenderTargetBitmap bmp = new RenderTargetBitmap(TargetSize, TargetSize, // Size
96, 96, // DPI
PixelFormats.Pbgra32);
DrawingVisual viz = new DrawingVisual();
using (DrawingContext dc = viz.RenderOpen())
{
dc.DrawGeometry(Brushes.Black, null, transformedGeometry);
}
bmp.Render(viz);
PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(bmp));
using (FileStream file = new FileStream(fileName, FileMode.Create))
pngEncoder.Save(file);
}
答案 1 :(得分:1)
// Create the bitmap we'll render to
RenderTargetBitmap bmp =
new RenderTargetBitmap(100, 100, // Size
96, 96, // DPI
PixelFormats.Pbgra32);
// Create a list of random circle geometries
List<Geometry> geoList = new List<Geometry>();
Random rand = new Random();
for (int i=0; i<10; i++)
{
double radius = rand.Next(5, 10);
Point center = new Point(rand.Next(25, 75), rand.Next(25,75));
geoList.Add(new EllipseGeometry(center, radius, radius));
}
// The light-weight visual element that will draw the geometries
DrawingVisual viz = new DrawingVisual();
using (DrawingContext dc = viz.RenderOpen())
{ // The DC lets us draw to the DrawingVisual directly
foreach (var g in geoList)
dc.DrawGeometry(Brushes.Red, null, g);
} // the DC is closed as it falls out of the using statement
// draw the visual on the bitmap
bmp.Render(viz);
// instantiate an encoder to save the file
PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
// add this bitmap to the encoders set of frames
pngEncoder.Frames.Add(BitmapFrame.Create(bmp));
// save the bitmap as an .png file
using (FileStream file = new FileStream("Spots.png", FileMode.Create))
pngEncoder.Save(file);
根据您对上述部分的评论,看起来您正在尝试为字体创建一个字形表并将其保存到图像文件中。以下是您完成此任务的方法:
// I'm generating the glyphs differently for testing.
// I tested with fontName="Arial"
Typeface face = new Typeface(fontName);
GlyphTypeface font;
if (!face.TryGetGlyphTypeface(out font))
return; // bail if something goes wrong
int ColumnCount = 10;
int MaxDrawCount = 30; // use int.MaxValue to draw them all
double fontSize = 50d;
// the height of each cell has to include over/underhanging glyphs
Size cellSize = new Size(fontSize, fontSize * font.Height);
var Glyphs = from glyphIndex in font.CharacterToGlyphMap.Values
select font.GetGlyphOutline(glyphIndex, fontSize, 1d);
// now create the visual we'll draw them to
DrawingVisual viz = new DrawingVisual();
int drawCount = -1;
using (DrawingContext dc = viz.RenderOpen())
{
foreach (var g in Glyphs)
{
drawCount++;
if (drawCount >= MaxDrawCount)
break; // don't draw more than you want
if (g.IsEmpty()) continue; // don't draw the blank ones
// center horizontally in the cell
double xOffset = (drawCount % ColumnCount) * cellSize.Width + cellSize.Width / 2d - g.Bounds.Width / 2d;
// place the character on the baseline of the cell
double yOffset = (drawCount / ColumnCount) * cellSize.Height + fontSize * font.Baseline;
dc.PushTransform(new TranslateTransform(xOffset, yOffset));
dc.DrawGeometry(Brushes.Red, null, g);
dc.Pop(); // get rid of the transform
}
}
int RowCount = drawCount / ColumnCount;
if (drawCount % ColumnCount != 0)
RowCount++; // to include partial rows
int bitWidth = (int)Math.Ceiling(cellSize.Width * ColumnCount);
int bitHeight = (int)Math.Ceiling(cellSize.Height * RowCount);
RenderTargetBitmap bmp = new RenderTargetBitmap(
bitWidth, bitHeight,
96, 96,
PixelFormats.Pbgra32);
bmp.Render(viz);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (FileStream file = new FileStream("FontTable.png", FileMode.Create))
encoder.Save(file);
答案 2 :(得分:1)
我用这个:
private void GenerateFontMap(string PathTofont, int GlyphsPerRow, int WidthAndHeight)
{
GlyphTypeface font = new GlyphTypeface(new Uri(PathTofont));
List<ushort> fontNum = new List<ushort>();
foreach (KeyValuePair<int, ushort> kvp in font.CharacterToGlyphMap)
{
fontNum.Add(kvp.Value);
}
if (fontNum.Count > 0)
{
int mapWidth = WidthAndHeight * GlyphsPerRow;
int mapHeight = WidthAndHeight * ((fontNum.Count + 1) / GlyphsPerRow + 1);
Bitmap b = new Bitmap(mapWidth, mapHeight);
Graphics g = Graphics.FromImage(b);
System.Windows.Media.Pen glyphPen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Black, 1);
Geometry glyphGeometry;
GeometryDrawing glyphDrawing;
PngBitmapEncoder encoder;
RenderTargetBitmap bmp;
DrawingVisual viz;
for (int i = 0; i < fontNum.Count; i++)
{
glyphGeometry = font.GetGlyphOutline(fontNum[i], WidthAndHeight, 1);
glyphDrawing = new GeometryDrawing(System.Windows.Media.Brushes.Black, glyphPen, glyphGeometry);
DrawingImage geometryImage = new DrawingImage(glyphDrawing);
geometryImage.Freeze();
viz = new DrawingVisual();
DrawingContext dc = viz.RenderOpen();
dc.DrawImage(geometryImage, new Rect(0, 0, geometryImage.Width, geometryImage.Height));
dc.Close();
bmp = new RenderTargetBitmap(WidthAndHeight, WidthAndHeight, 96, 96, PixelFormats.Pbgra32);
bmp.Render(viz);
encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
MemoryStream myStream = new MemoryStream();
encoder.Save(myStream);
g.DrawImage(System.Drawing.Bitmap.FromStream(myStream), new PointF((i - (i / GlyphsPerRow) * GlyphsPerRow) * WidthAndHeight, i / GlyphsPerRow * WidthAndHeight));
}
g.Dispose();
b.Save("map.png", ImageFormat.Png);
b.Dispose();
}
}
答案 3 :(得分:-1)
查看我的其他answer。通常,您应该使用RenderTargetBitmap类。