I'm trying to create images from symbols so that I can create a custom symbol dialog. Found this sample code on the ESRI forums and it workes great on almost all symbols. I'm having problems with a IMultiLayerFillSymbol that has a IPictureFillSymbol on one of it's layers. It's throwing an exception on symbol.Draw(geometry);
Does anyone know if there is any additional steps that has to taken to get it to work with a IMultiLayerFillSymbol?
static public Image ImageFromSymbol(ISymbol symbol, Int32 width, Int32 height)
{
try
{
Bitmap bitmap = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bitmap);
IntPtr hdc = g.GetHdc();
IGeometry geometry = null;
if (symbol is IMarkerSymbol)
{
IPoint point = new PointClass();
point.X = (width / 2);
point.Y = (height / 2);
geometry = point;
}
else if (symbol is ILineSymbol)
{
IPolyline line = new PolylineClass();
IPoint ptFrom = new PointClass();
IPoint ptTo = new PointClass();
ptFrom.X = 3; ptFrom.Y = (height / 2);
ptTo.X = (width - 3); ptTo.Y = ptFrom.Y;
line.FromPoint = ptFrom;
line.ToPoint = ptTo;
geometry = line;
}
else
{
IEnvelope bounds = new EnvelopeClass();
bounds.XMin = 1; bounds.XMax = width - 1;
bounds.YMin = 1; bounds.YMax = height - 1;
geometry = bounds;
}
symbol.SetupDC(hdc.ToInt32(), null);
symbol.Draw(geometry);
symbol.ResetDC();
g.ReleaseHdc(hdc);
g.Dispose();
return bitmap as Image;
}
catch (Exception ex)
{
Debug.Print(ex.Message);
return null;
}
}
Update, Added the following code to make it work:
Updated the ImageFromSymbol metod with:
ITransformation pTransformation = CreateTransFromDC(
hDC, size.Width, size.Height);
pSymbol.SetupDC(hDC.ToInt32(), pTransformation);
Added:
private const int LOGPIXELSY = 90;
[DllImport("GDI32.dll", EntryPoint = "GetDeviceCaps",
ExactSpelling = true, SetLastError = true)]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
private static ITransformation CreateTransFromDC(IntPtr hDC,
int lWidth, int lHeight) {
// Calculate the parameters for the new transformation,
// based on the dimensions passed to this function.
try {
IEnvelope pBoundsEnvelope = new EnvelopeClass();
pBoundsEnvelope.PutCoords(0.0, 0.0, (double)lWidth,
(double)lHeight);
tagRECT deviceRect;
deviceRect.left = 0;
deviceRect.top = 0;
deviceRect.right = lWidth;
deviceRect.bottom = lHeight;
int dpi = GetDeviceCaps(hDC, LOGPIXELSY);
if (dpi == 0) {
throw new Exception(
"Could not retrieve Resolution from device context.");
}
// Create a new display transformation and set its properties
IDisplayTransformation newTrans =
new DisplayTransformationClass();
newTrans.VisibleBounds = pBoundsEnvelope;
newTrans.Bounds = pBoundsEnvelope;
newTrans.set_DeviceFrame(ref deviceRect);
newTrans.Resolution = dpi;
return newTrans;
}
catch {
return null;
}
}