4

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;
 }
 }
asked Oct 6, 2010 at 14:43
1
  • Yes, when I tried to loop through layers of the IMultiLayerFillSymbol and drawing the individual IPictureFillSymbol it throws the same exception. Commented Oct 6, 2010 at 14:54

1 Answer 1

3

I'd try creating a new DisplayTransformation class and passing it to SetupDC (instead of null). I think you'll need to set the device frame to match the pixel extent, along with visible extent. Then pass an envelope to Draw that matches the visible extent.

Update: try Richie Carmichael's SymbolToBitmap function here.

answered Oct 6, 2010 at 15:22
3
  • Great! Adding a ITransformation solved the problem! Commented Oct 6, 2010 at 15:57
  • @seems that the url is broken :( Commented Nov 9, 2015 at 10:20
  • 1
    @vinayan looks like Richie also uses SymboltoBitmap here kiwigis.blogspot.com/2009/05/… Commented Nov 9, 2015 at 21:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.