private void WriteImageParts(DrawingsPart dp)
        {
            ImagePart imgp;
            Xdr.WorksheetDrawing wsd = dp.WorksheetDrawing;
            SLRowProperties rp;
            SLColumnProperties cp;

            #region Charts
            if (slws.Charts.Count > 0)
            {
                int FromAnchorRowIndex = 0;
                long FromAnchorRowOffset = 0;
                int FromAnchorColumnIndex = 0;
                long FromAnchorColumnOffset = 0;
                int ToAnchorRowIndex = 4;
                long ToAnchorRowOffset = 0;
                int ToAnchorColumnIndex = 4;
                long ToAnchorColumnOffset = 0;
                double fTemp = 0;

                ChartPart chartp;

                Xdr.GraphicFrame gf;

                foreach (Charts.SLChart Chart in slws.Charts)
                {
                    chartp = dp.AddNewPart<ChartPart>();
                    chartp.ChartSpace = Chart.ToChartSpace(ref chartp);

                    gf = new Xdr.GraphicFrame();
                    gf.Macro = string.Empty;
                    gf.NonVisualGraphicFrameProperties = new Xdr.NonVisualGraphicFrameProperties();
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties = new Xdr.NonVisualDrawingProperties();
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Id = slws.NextWorksheetDrawingId;
                    ++slws.NextWorksheetDrawingId;
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name = Chart.ChartName;
                    // alt text for charts
                    //...gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Description = "";
                    gf.NonVisualGraphicFrameProperties.NonVisualGraphicFrameDrawingProperties = new Xdr.NonVisualGraphicFrameDrawingProperties();

                    gf.Transform = new Xdr.Transform();
                    gf.Transform.Offset = new A.Offset() { X = 0, Y = 0 };
                    gf.Transform.Extents = new A.Extents() { Cx = 0, Cy = 0 };

                    gf.Graphic = new A.Graphic();
                    gf.Graphic.GraphicData = new A.GraphicData();
                    gf.Graphic.GraphicData.Uri = SLConstants.NamespaceC;
                    gf.Graphic.GraphicData.Append(new C.ChartReference() { Id = dp.GetIdOfPart(chartp) });

                    FromAnchorRowIndex = (int)Math.Floor(Chart.TopPosition);
                    fTemp = Chart.TopPosition - FromAnchorRowIndex;
                    FromAnchorRowOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultRowHeightInEMU);
                    if (slws.RowProperties.ContainsKey(FromAnchorRowIndex + 1))
                    {
                        rp = slws.RowProperties[FromAnchorRowIndex + 1];
                        if (rp.HasHeight) FromAnchorRowOffset = (long)(fTemp * rp.HeightInEMU);
                    }

                    FromAnchorColumnIndex = (int)Math.Floor(Chart.LeftPosition);
                    fTemp = Chart.LeftPosition - FromAnchorColumnIndex;

                    FromAnchorColumnOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultColumnWidthInEMU);

                    if (slws.ColumnProperties.ContainsKey(FromAnchorColumnIndex + 1))
                    {
                        cp = slws.ColumnProperties[FromAnchorColumnIndex + 1];
                        if (cp.HasWidth)
                        {
                            FromAnchorColumnOffset = (long)(fTemp * cp.WidthInEMU);
                        }
                    }

                    ToAnchorRowIndex = (int)Math.Floor(Chart.BottomPosition);
                    fTemp = Chart.BottomPosition - ToAnchorRowIndex;
                    ToAnchorRowOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultRowHeightInEMU);
                    if (slws.RowProperties.ContainsKey(ToAnchorRowIndex + 1))
                    {
                        rp = slws.RowProperties[ToAnchorRowIndex + 1];
                        if (rp.HasHeight) ToAnchorRowOffset = (long)(fTemp * rp.HeightInEMU);
                    }

                    ToAnchorColumnIndex = (int)Math.Floor(Chart.RightPosition);
                    fTemp = Chart.RightPosition - ToAnchorColumnIndex;

                    ToAnchorColumnOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultColumnWidthInEMU);

                    if (slws.ColumnProperties.ContainsKey(ToAnchorColumnIndex + 1))
                    {
                        cp = slws.ColumnProperties[ToAnchorColumnIndex + 1];
                        if (cp.HasWidth)
                        {
                            ToAnchorColumnOffset = (long)(fTemp * cp.WidthInEMU);
                        }
                    }

                    Xdr.TwoCellAnchor tcanchor = new Xdr.TwoCellAnchor();
                    tcanchor.FromMarker = new Xdr.FromMarker();
                    tcanchor.FromMarker.RowId = new Xdr.RowId(FromAnchorRowIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.RowOffset = new Xdr.RowOffset(FromAnchorRowOffset.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.ColumnId = new Xdr.ColumnId(FromAnchorColumnIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.ColumnOffset = new Xdr.ColumnOffset(FromAnchorColumnOffset.ToString(CultureInfo.InvariantCulture));

                    tcanchor.ToMarker = new Xdr.ToMarker();
                    tcanchor.ToMarker.RowId = new Xdr.RowId(ToAnchorRowIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.RowOffset = new Xdr.RowOffset(ToAnchorRowOffset.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.ColumnId = new Xdr.ColumnId(ToAnchorColumnIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.ColumnOffset = new Xdr.ColumnOffset(ToAnchorColumnOffset.ToString(CultureInfo.InvariantCulture));

                    tcanchor.Append(gf);
                    tcanchor.Append(new Xdr.ClientData());

                    wsd.Append(tcanchor);
                    wsd.Save(dp);
                }
            }
            #endregion

            #region Pictures
            if (slws.Pictures.Count > 0)
            {
                foreach (Drawing.SLPicture Picture in slws.Pictures)
                {
                    imgp = dp.AddImagePart(Picture.PictureImagePartType);

                    if (Picture.DataIsInFile)
                    {
                        using (FileStream fs = new FileStream(Picture.PictureFileName, FileMode.Open))
                        {
                            imgp.FeedData(fs);
                        }
                    }
                    else
                    {
                        using (MemoryStream ms = new MemoryStream(Picture.PictureByteData))
                        {
                            imgp.FeedData(ms);
                        }
                    }

                    Xdr.Picture pic = new Xdr.Picture();
                    pic.NonVisualPictureProperties = new Xdr.NonVisualPictureProperties();

                    pic.NonVisualPictureProperties.NonVisualDrawingProperties = new Xdr.NonVisualDrawingProperties();
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Id = slws.NextWorksheetDrawingId;
                    ++slws.NextWorksheetDrawingId;
                    // recommendation is to set as the actual filename, but we'll follow Excel here...
                    // Note: the name value can be used multiple times without Excel choking.
                    // So for example, you can have two pictures with "Picture 1".
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Name = string.Format("Picture {0}", dp.ImageParts.Count());
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Description = Picture.AlternativeText;
                    // hlinkClick and hlinkHover as children

                    if (Picture.HasUri)
                    {
                        HyperlinkRelationship hlinkrel = dp.AddHyperlinkRelationship(new System.Uri(Picture.HyperlinkUri, Picture.HyperlinkUriKind), Picture.IsHyperlinkExternal);
                        pic.NonVisualPictureProperties.NonVisualDrawingProperties.HyperlinkOnClick = new A.HyperlinkOnClick() { Id = hlinkrel.Id };
                    }

                    pic.NonVisualPictureProperties.NonVisualPictureDrawingProperties = new Xdr.NonVisualPictureDrawingProperties();

                    pic.BlipFill = new Xdr.BlipFill();
                    pic.BlipFill.Blip = new A.Blip();
                    pic.BlipFill.Blip.Embed = dp.GetIdOfPart(imgp);
                    if (Picture.CompressionState != A.BlipCompressionValues.None)
                    {
                        pic.BlipFill.Blip.CompressionState = Picture.CompressionState;
                    }

                    if (Picture.Brightness != 0 || Picture.Contrast != 0)
                    {
                        A.LuminanceEffect lumeffect = new A.LuminanceEffect();
                        if (Picture.Brightness != 0) lumeffect.Brightness = Convert.ToInt32(Picture.Brightness * 1000);
                        if (Picture.Contrast != 0) lumeffect.Contrast = Convert.ToInt32(Picture.Contrast * 1000);
                        pic.BlipFill.Blip.Append(lumeffect);
                    }

                    pic.BlipFill.SourceRectangle = new A.SourceRectangle();
                    pic.BlipFill.Append(new A.Stretch() { FillRectangle = new A.FillRectangle() });

                    Picture.ShapeProperties.BlackWhiteMode = A.BlackWhiteModeValues.Auto;
                    Picture.ShapeProperties.HasTransform2D = true;
                    Picture.ShapeProperties.Transform2D.HasOffset = true;
                    Picture.ShapeProperties.Transform2D.HasExtents = true;

                    // not supporting yet because you need to change the positional offsets too.
                    //if (Picture.RotationAngle != 0)
                    //{
                    //    pic.ShapeProperties.Transform2D.Rotation = Convert.ToInt32(Picture.RotationAngle * (decimal)SLConstants.DegreeToAngleRepresentation);
                    //}

                    // used when it's relative positioning
                    // these are the actual values used, so it's 1 less than the given anchor indices.
                    int iColumnId = 0, iRowId = 0;
                    long lColumnOffset = 0, lRowOffset = 0;
                    if (Picture.UseRelativePositioning)
                    {
                        iColumnId = Picture.AnchorColumnIndex - 1;
                        iRowId = Picture.AnchorRowIndex - 1;

                        long lOffset = 0;
                        long lOffsetBuffer = 0;
                        int i;

                        for (i = 1; i <= iColumnId; ++i)
                        {
                            if (slws.ColumnProperties.ContainsKey(i))
                            {
                                cp = slws.ColumnProperties[i];
                                if (cp.HasWidth)
                                {
                                    lOffsetBuffer += cp.WidthInEMU;
                                }
                                else
                                {
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                }
                            }
                            else
                            {
                                // we use the current worksheet's column width
                                lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                            }
                        }
                        lOffsetBuffer += Picture.OffsetX;
                        lOffset = lOffsetBuffer;

                        if (lOffset <= 0)
                        {
                            // in case the given offset is so negative, it pushes the sum to negative
                            // We use "<= 0" here, so the else part assumes a positive offset
                            iColumnId = 0;
                            lColumnOffset = 0;
                        }
                        else
                        {
                            lOffsetBuffer = 0;
                            i = 1;

                            while (lOffset > lOffsetBuffer)
                            {
                                iColumnId = i - 1;
                                lColumnOffset = lOffset - lOffsetBuffer;

                                if (slws.ColumnProperties.ContainsKey(i))
                                {
                                    cp = slws.ColumnProperties[i];
                                    if (cp.HasWidth)
                                    {
                                        lOffsetBuffer += cp.WidthInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's column width
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                }
                                ++i;
                            }
                        }

                        Picture.ShapeProperties.Transform2D.Offset.X = lColumnOffset;

                        lOffsetBuffer = 0;
                        for (i = 1; i <= iRowId; ++i)
                        {
                            if (slws.RowProperties.ContainsKey(i))
                            {
                                rp = slws.RowProperties[i];
                                if (rp.HasHeight)
                                {
                                    lOffsetBuffer += rp.HeightInEMU;
                                }
                                else
                                {
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                }
                            }
                            else
                            {
                                // we use the current worksheet's row height
                                lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                            }
                        }
                        lOffsetBuffer += Picture.OffsetY;
                        lOffset = lOffsetBuffer;

                        if (lOffset <= 0)
                        {
                            // in case the given offset is so negative, it pushes the sum to negative
                            // We use "<= 0" here, so the else part assumes a positive offset
                            iRowId = 0;
                            lRowOffset = 0;
                        }
                        else
                        {
                            lOffsetBuffer = 0;
                            i = 1;

                            while (lOffset > lOffsetBuffer)
                            {
                                iRowId = i - 1;
                                lRowOffset = lOffset - lOffsetBuffer;

                                if (slws.RowProperties.ContainsKey(i))
                                {
                                    rp = slws.RowProperties[i];
                                    if (rp.HasHeight)
                                    {
                                        lOffsetBuffer += rp.HeightInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's row height
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                }
                                ++i;
                            }
                        }

                        Picture.ShapeProperties.Transform2D.Offset.Y = lRowOffset;
                    }
                    else
                    {
                        Picture.ShapeProperties.Transform2D.Offset.X = 0;
                        Picture.ShapeProperties.Transform2D.Offset.Y = 0;
                    }

                    Picture.ShapeProperties.Transform2D.Extents.Cx = Picture.WidthInEMU;
                    Picture.ShapeProperties.Transform2D.Extents.Cy = Picture.HeightInEMU;

                    Picture.ShapeProperties.HasPresetGeometry = true;
                    Picture.ShapeProperties.PresetGeometry = Picture.PictureShape;

                    pic.ShapeProperties = Picture.ShapeProperties.ToXdrShapeProperties();

                    Xdr.ClientData clientdata = new Xdr.ClientData();
                    // the properties are true by default
                    if (!Picture.LockWithSheet) clientdata.LockWithSheet = false;
                    if (!Picture.PrintWithSheet) clientdata.PrintWithSheet = false;

                    if (Picture.UseRelativePositioning)
                    {
                        Xdr.OneCellAnchor ocanchor = new Xdr.OneCellAnchor();
                        ocanchor.FromMarker = new Xdr.FromMarker();
                        // Subtract 1 because picture goes to bottom right corner
                        // Subtracting 1 makes it more intuitive that (1,1) means top-left corner of (1,1)
                        ocanchor.FromMarker.ColumnId = new Xdr.ColumnId() { Text = iColumnId.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.ColumnOffset = new Xdr.ColumnOffset() { Text = lColumnOffset.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.RowId = new Xdr.RowId() { Text = iRowId.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.RowOffset = new Xdr.RowOffset() { Text = lRowOffset.ToString(CultureInfo.InvariantCulture) };

                        ocanchor.Extent = new Xdr.Extent();
                        ocanchor.Extent.Cx = Picture.WidthInEMU;
                        ocanchor.Extent.Cy = Picture.HeightInEMU;

                        ocanchor.Append(pic);
                        ocanchor.Append(clientdata);
                        wsd.Append(ocanchor);
                    }
                    else
                    {
                        Xdr.AbsoluteAnchor absanchor = new Xdr.AbsoluteAnchor();
                        absanchor.Position = new Xdr.Position();
                        absanchor.Position.X = Picture.OffsetX;
                        absanchor.Position.Y = Picture.OffsetY;

                        absanchor.Extent = new Xdr.Extent();
                        absanchor.Extent.Cx = Picture.WidthInEMU;
                        absanchor.Extent.Cy = Picture.HeightInEMU;

                        absanchor.Append(pic);
                        absanchor.Append(clientdata);
                        wsd.Append(absanchor);
                    }

                    wsd.Save(dp);
                }
            }
            #endregion
        }
        private void WriteImageParts(DrawingsPart dp)
        {
            ImagePart imgp;
            Xdr.WorksheetDrawing wsd = dp.WorksheetDrawing;
            SLRowProperties rp;
            SLColumnProperties cp;

            #region Charts
            if (slws.Charts.Count > 0)
            {
                int FromAnchorRowIndex = 0;
                long FromAnchorRowOffset = 0;
                int FromAnchorColumnIndex = 0;
                long FromAnchorColumnOffset = 0;
                int ToAnchorRowIndex = 4;
                long ToAnchorRowOffset = 0;
                int ToAnchorColumnIndex = 4;
                long ToAnchorColumnOffset = 0;
                double fTemp = 0;

                ChartPart chartp;

                Xdr.GraphicFrame gf;

                foreach (Charts.SLChart Chart in slws.Charts)
                {
                    chartp = dp.AddNewPart<ChartPart>();
                    chartp.ChartSpace = Chart.ToChartSpace(ref chartp);

                    gf = new Xdr.GraphicFrame();
                    gf.Macro = string.Empty;
                    gf.NonVisualGraphicFrameProperties = new Xdr.NonVisualGraphicFrameProperties();
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties = new Xdr.NonVisualDrawingProperties();
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Id = slws.NextWorksheetDrawingId;
                    ++slws.NextWorksheetDrawingId;
                    gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name = Chart.ChartName;
                    // alt text for charts
                    //...gf.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Description = "";
                    gf.NonVisualGraphicFrameProperties.NonVisualGraphicFrameDrawingProperties = new Xdr.NonVisualGraphicFrameDrawingProperties();

                    gf.Transform = new Xdr.Transform();
                    gf.Transform.Offset = new A.Offset() { X = 0, Y = 0 };
                    gf.Transform.Extents = new A.Extents() { Cx = 0, Cy = 0 };

                    gf.Graphic = new A.Graphic();
                    gf.Graphic.GraphicData = new A.GraphicData();
                    gf.Graphic.GraphicData.Uri = "http://schemas.openxmlformats.org/drawingml/2006/chart";
                    gf.Graphic.GraphicData.Append(new C.ChartReference() { Id = dp.GetIdOfPart(chartp) });

                    FromAnchorRowIndex = (int)Math.Floor(Chart.TopPosition);
                    fTemp = Chart.TopPosition - FromAnchorRowIndex;
                    FromAnchorRowOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultRowHeightInEMU);
                    if (slws.RowProperties.ContainsKey(FromAnchorRowIndex + 1))
                    {
                        rp = slws.RowProperties[FromAnchorRowIndex + 1];
                        if (rp.HasHeight) FromAnchorRowOffset = (long)(fTemp * rp.HeightInEMU);
                    }

                    FromAnchorColumnIndex = (int)Math.Floor(Chart.LeftPosition);
                    fTemp = Chart.LeftPosition - FromAnchorColumnIndex;
                    FromAnchorColumnOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultColumnWidthInEMU);
                    if (slws.ColumnProperties.ContainsKey(FromAnchorColumnIndex + 1))
                    {
                        cp = slws.ColumnProperties[FromAnchorColumnIndex + 1];
                        if (cp.HasWidth) FromAnchorColumnOffset = (long)(fTemp * cp.WidthInEMU);
                    }

                    ToAnchorRowIndex = (int)Math.Floor(Chart.BottomPosition);
                    fTemp = Chart.BottomPosition - ToAnchorRowIndex;
                    ToAnchorRowOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultRowHeightInEMU);
                    if (slws.RowProperties.ContainsKey(ToAnchorRowIndex + 1))
                    {
                        rp = slws.RowProperties[ToAnchorRowIndex + 1];
                        if (rp.HasHeight) ToAnchorRowOffset = (long)(fTemp * rp.HeightInEMU);
                    }

                    ToAnchorColumnIndex = (int)Math.Floor(Chart.RightPosition);
                    fTemp = Chart.RightPosition - ToAnchorColumnIndex;
                    ToAnchorColumnOffset = (long)(fTemp * slws.SheetFormatProperties.DefaultColumnWidthInEMU);
                    if (slws.ColumnProperties.ContainsKey(ToAnchorColumnIndex + 1))
                    {
                        cp = slws.ColumnProperties[ToAnchorColumnIndex + 1];
                        if (cp.HasWidth) ToAnchorColumnOffset = (long)(fTemp * cp.WidthInEMU);
                    }

                    Xdr.TwoCellAnchor tcanchor = new Xdr.TwoCellAnchor();
                    tcanchor.FromMarker = new Xdr.FromMarker();
                    tcanchor.FromMarker.RowId = new Xdr.RowId(FromAnchorRowIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.RowOffset = new Xdr.RowOffset(FromAnchorRowOffset.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.ColumnId = new Xdr.ColumnId(FromAnchorColumnIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.FromMarker.ColumnOffset = new Xdr.ColumnOffset(FromAnchorColumnOffset.ToString(CultureInfo.InvariantCulture));

                    tcanchor.ToMarker = new Xdr.ToMarker();
                    tcanchor.ToMarker.RowId = new Xdr.RowId(ToAnchorRowIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.RowOffset = new Xdr.RowOffset(ToAnchorRowOffset.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.ColumnId = new Xdr.ColumnId(ToAnchorColumnIndex.ToString(CultureInfo.InvariantCulture));
                    tcanchor.ToMarker.ColumnOffset = new Xdr.ColumnOffset(ToAnchorColumnOffset.ToString(CultureInfo.InvariantCulture));

                    tcanchor.Append(gf);
                    tcanchor.Append(new Xdr.ClientData());

                    wsd.Append(tcanchor);
                    wsd.Save(dp);
                }
            }
            #endregion

            #region Pictures
            if (slws.Pictures.Count > 0)
            {
                foreach (Drawing.SLPicture Picture in slws.Pictures)
                {
                    imgp = dp.AddImagePart(Picture.PictureImagePartType);

                    if (Picture.DataIsInFile)
                    {
                        using (FileStream fs = new FileStream(Picture.PictureFileName, FileMode.Open))
                        {
                            imgp.FeedData(fs);
                        }
                    }
                    else
                    {
                        using (MemoryStream ms = new MemoryStream(Picture.PictureByteData))
                        {
                            imgp.FeedData(ms);
                        }
                    }

                    Xdr.Picture pic = new Xdr.Picture();
                    pic.NonVisualPictureProperties = new Xdr.NonVisualPictureProperties();

                    pic.NonVisualPictureProperties.NonVisualDrawingProperties = new Xdr.NonVisualDrawingProperties();
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Id = slws.NextWorksheetDrawingId;
                    ++slws.NextWorksheetDrawingId;
                    // recommendation is to set as the actual filename, but we'll follow Excel here...
                    // Note: the name value can be used multiple times without Excel choking.
                    // So for example, you can have two pictures with "Picture 1".
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Name = string.Format("Picture {0}", dp.ImageParts.Count());
                    pic.NonVisualPictureProperties.NonVisualDrawingProperties.Description = Picture.AlternativeText;
                    // hlinkClick and hlinkHover as children

                    if (Picture.HasUri)
                    {
                        HyperlinkRelationship hlinkrel = dp.AddHyperlinkRelationship(new System.Uri(Picture.HyperlinkUri, Picture.HyperlinkUriKind), Picture.IsHyperlinkExternal);
                        pic.NonVisualPictureProperties.NonVisualDrawingProperties.HyperlinkOnClick = new A.HyperlinkOnClick() { Id = hlinkrel.Id };
                    }

                    pic.NonVisualPictureProperties.NonVisualPictureDrawingProperties = new Xdr.NonVisualPictureDrawingProperties();

                    pic.BlipFill = new Xdr.BlipFill();
                    pic.BlipFill.Blip = new A.Blip();
                    pic.BlipFill.Blip.Embed = dp.GetIdOfPart(imgp);
                    if (Picture.CompressionState != A.BlipCompressionValues.None)
                    {
                        pic.BlipFill.Blip.CompressionState = Picture.CompressionState;
                    }

                    if (Picture.Brightness != 0 || Picture.Contrast != 0)
                    {
                        A.LuminanceEffect lumeffect = new A.LuminanceEffect();
                        if (Picture.Brightness != 0) lumeffect.Brightness = Convert.ToInt32(Picture.Brightness * 1000);
                        if (Picture.Contrast != 0) lumeffect.Contrast = Convert.ToInt32(Picture.Contrast * 1000);
                        pic.BlipFill.Blip.Append(lumeffect);
                    }

                    pic.BlipFill.SourceRectangle = new A.SourceRectangle();
                    pic.BlipFill.Append(new A.Stretch() { FillRectangle = new A.FillRectangle() });

                    pic.ShapeProperties = new Xdr.ShapeProperties();
                    pic.ShapeProperties.BlackWhiteMode = A.BlackWhiteModeValues.Auto;
                    pic.ShapeProperties.Transform2D = new A.Transform2D();

                    // not supporting yet because you need to change the positional offsets too.
                    //if (Picture.RotationAngle != 0)
                    //{
                    //    pic.ShapeProperties.Transform2D.Rotation = Convert.ToInt32(Picture.RotationAngle * (decimal)SLConstants.DegreeToAngleRepresentation);
                    //}

                    pic.ShapeProperties.Transform2D.Offset = new A.Offset();

                    // used when it's relative positioning
                    // these are the actual values used, so it's 1 less than the given anchor indices.
                    int iColumnId = 0, iRowId = 0;
                    long lColumnOffset = 0, lRowOffset = 0;
                    if (Picture.UseRelativePositioning)
                    {
                        iColumnId = Picture.AnchorColumnIndex - 1;
                        iRowId = Picture.AnchorRowIndex - 1;

                        long lOffset = 0;
                        long lOffsetBuffer = 0;
                        int i;

                        if (iColumnId > 0)
                        {
                            for (i = 1; i <= iColumnId; ++i)
                            {
                                if (slws.ColumnProperties.ContainsKey(i))
                                {
                                    cp = slws.ColumnProperties[i];
                                    if (cp.HasWidth)
                                    {
                                        lOffsetBuffer += cp.WidthInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's column width
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                }
                            }
                        }
                        lOffsetBuffer += Picture.OffsetX;
                        lOffset = lOffsetBuffer;

                        if (lOffset <= 0)
                        {
                            // in case the given offset is so negative, it pushes the sum to negative
                            // We use "<= 0" here, so the else part assumes a positive offset
                            iColumnId = 0;
                            lColumnOffset = 0;
                        }
                        else
                        {
                            lOffsetBuffer = 0;
                            i = 1;

                            while (lOffset > lOffsetBuffer)
                            {
                                iColumnId = i - 1;
                                lColumnOffset = lOffset - lOffsetBuffer;

                                if (slws.ColumnProperties.ContainsKey(i))
                                {
                                    cp = slws.ColumnProperties[i];
                                    if (cp.HasWidth)
                                    {
                                        lOffsetBuffer += cp.WidthInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's column width
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultColumnWidthInEMU;
                                }
                                ++i;
                            }
                        }

                        pic.ShapeProperties.Transform2D.Offset.X = lColumnOffset;

                        lOffsetBuffer = 0;
                        if (iRowId > 0)
                        {
                            for (i = 1; i <= iRowId; ++i)
                            {
                                if (slws.RowProperties.ContainsKey(i))
                                {
                                    rp = slws.RowProperties[i];
                                    if (rp.HasHeight)
                                    {
                                        lOffsetBuffer += rp.HeightInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's row height
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                }
                            }
                        }
                        lOffsetBuffer += Picture.OffsetY;
                        lOffset = lOffsetBuffer;

                        if (lOffset <= 0)
                        {
                            // in case the given offset is so negative, it pushes the sum to negative
                            // We use "<= 0" here, so the else part assumes a positive offset
                            iRowId = 0;
                            lRowOffset = 0;
                        }
                        else
                        {
                            lOffsetBuffer = 0;
                            i = 1;

                            while (lOffset > lOffsetBuffer)
                            {
                                iRowId = i - 1;
                                lRowOffset = lOffset - lOffsetBuffer;

                                if (slws.RowProperties.ContainsKey(i))
                                {
                                    rp = slws.RowProperties[i];
                                    if (rp.HasHeight)
                                    {
                                        lOffsetBuffer += rp.HeightInEMU;
                                    }
                                    else
                                    {
                                        lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                    }
                                }
                                else
                                {
                                    // we use the current worksheet's row height
                                    lOffsetBuffer += slws.SheetFormatProperties.DefaultRowHeightInEMU;
                                }
                                ++i;
                            }
                        }

                        pic.ShapeProperties.Transform2D.Offset.Y = lRowOffset;
                    }
                    else
                    {
                        pic.ShapeProperties.Transform2D.Offset.X = 0;
                        pic.ShapeProperties.Transform2D.Offset.Y = 0;
                    }
                    pic.ShapeProperties.Transform2D.Extents = new A.Extents();
                    pic.ShapeProperties.Transform2D.Extents.Cx = Picture.WidthInEMU;
                    pic.ShapeProperties.Transform2D.Extents.Cy = Picture.HeightInEMU;
                    pic.ShapeProperties.Append(new A.PresetGeometry() { Preset = Picture.PictureShape, AdjustValueList = new A.AdjustValueList() });

                    switch (Picture.FillType)
                    {
                        case Drawing.SLPicture.SLPictureFillType.None:
                            pic.ShapeProperties.Append(new A.NoFill());
                            break;
                        case Drawing.SLPicture.SLPictureFillType.Solid:
                            A.SolidFill solidfill = new A.SolidFill();
                            solidfill.InnerXml = Picture.FillClassInnerXml;
                            pic.ShapeProperties.Append(solidfill);
                            break;
                        default:
                            pic.ShapeProperties.Append(new A.NoFill());
                            break;
                    }

                    if (Picture.HasOutline)
                    {
                        A.Outline outline = new A.Outline();
                        if (Picture.PictureOutline.Width != null)
                        {
                            outline.Width = Picture.PictureOutline.Width.Value;
                        }
                        if (Picture.PictureOutline.CompoundLineType != null)
                        {
                            outline.CompoundLineType = Picture.PictureOutline.CompoundLineType.Value;
                        }
                        if (Picture.PictureOutline.CapType != null)
                        {
                            outline.CapType = Picture.PictureOutline.CapType.Value;
                        }

                        outline.Append((A.SolidFill)Picture.PictureOutlineFill.CloneNode(true));

                        foreach (var child in Picture.PictureOutlineFill.ChildElements)
                        {
                            if (child is A.PresetDash)
                            {
                                outline.Append((A.PresetDash)child.CloneNode(true));
                            }
                            else if (child is A.Round)
                            {
                                outline.Append((A.Round)child.CloneNode(true));
                            }
                            else if (child is A.Bevel)
                            {
                                outline.Append((A.Bevel)child.CloneNode(true));
                            }
                            else if (child is A.Miter)
                            {
                                outline.Append((A.Miter)child.CloneNode(true));
                            }
                        }

                        pic.ShapeProperties.Append(outline);
                    }

                    if (Picture.HasEffectList)
                    {
                        A.EffectList effectlist = new A.EffectList();

                        if (Picture.HasGlow)
                        {
                            A.Glow glow = new A.Glow();
                            glow.Radius = Picture.GlowRadius;
                            glow.InnerXml = Picture.GlowColorInnerXml;
                            effectlist.Append(glow);
                        }

                        if (Picture.HasInnerShadow)
                        {
                            effectlist.Append((A.InnerShadow)Picture.PictureInnerShadow.CloneNode(true));
                        }

                        if (Picture.HasOuterShadow)
                        {
                            effectlist.Append((A.OuterShadow)Picture.PictureOuterShadow.CloneNode(true));
                        }

                        if (Picture.HasReflection)
                        {
                            A.Reflection refl = new A.Reflection();
                            if (Picture.ReflectionBlurRadius != 0) refl.BlurRadius = Picture.ReflectionBlurRadius;
                            if (Picture.ReflectionStartOpacity != 100000) refl.StartOpacity = Picture.ReflectionStartOpacity;
                            if (Picture.ReflectionStartPosition != 0) refl.StartPosition = Picture.ReflectionStartPosition;
                            if (Picture.ReflectionEndAlpha != 0) refl.EndAlpha = Picture.ReflectionEndAlpha;
                            if (Picture.ReflectionEndPosition != 100000) refl.EndPosition = Picture.ReflectionEndPosition;
                            if (Picture.ReflectionDistance != 0) refl.Distance = Picture.ReflectionDistance;
                            if (Picture.ReflectionDirection != 0) refl.Direction = Picture.ReflectionDirection;
                            if (Picture.ReflectionFadeDirection != 5400000) refl.FadeDirection = Picture.ReflectionFadeDirection;
                            if (Picture.ReflectionHorizontalRatio != 100000) refl.HorizontalRatio = Picture.ReflectionHorizontalRatio;
                            if (Picture.ReflectionVerticalRatio != 100000) refl.VerticalRatio = Picture.ReflectionVerticalRatio;
                            if (Picture.ReflectionHorizontalSkew != 0) refl.HorizontalSkew = Picture.ReflectionHorizontalSkew;
                            if (Picture.ReflectionVerticalSkew != 0) refl.VerticalSkew = Picture.ReflectionVerticalSkew;
                            if (Picture.ReflectionAlignment != A.RectangleAlignmentValues.Bottom) refl.Alignment = Picture.ReflectionAlignment;
                            if (!Picture.ReflectionRotateWithShape) refl.RotateWithShape = false;
                            effectlist.Append(refl);
                        }

                        if (Picture.HasSoftEdge)
                        {
                            A.SoftEdge softedge = new A.SoftEdge();
                            softedge.Radius = Picture.SoftEdgeRadius;
                            effectlist.Append(softedge);
                        }

                        pic.ShapeProperties.Append(effectlist);
                    }

                    if (Picture.HasScene3D)
                    {
                        A.Scene3DType scene3d = new A.Scene3DType();
                        scene3d.Camera = new A.Camera();
                        scene3d.Camera.Preset = Picture.CameraPreset;
                        scene3d.Camera.FieldOfView = Picture.CameraFieldOfView;
                        // default is 100%
                        if (Picture.CameraZoom != 100000)
                        {
                            scene3d.Camera.Zoom = Picture.CameraZoom;
                        }

                        if (Picture.CameraLatitude != 0 || Picture.CameraLongitude != 0 || Picture.CameraRevolution != 0)
                        {
                            scene3d.Camera.Rotation = new A.Rotation();
                            scene3d.Camera.Rotation.Latitude = Picture.CameraLatitude;
                            scene3d.Camera.Rotation.Longitude = Picture.CameraLongitude;
                            scene3d.Camera.Rotation.Revolution = Picture.CameraRevolution;
                        }

                        scene3d.LightRig = new A.LightRig();
                        scene3d.LightRig.Rig = Picture.LightRigType;
                        scene3d.LightRig.Direction = Picture.LightRigDirection;

                        if (Picture.LightRigLatitude != 0 || Picture.LightRigLongitude != 0 || Picture.LightRigRevolution != 0)
                        {
                            scene3d.LightRig.Rotation = new A.Rotation();
                            scene3d.LightRig.Rotation.Latitude = Picture.LightRigLatitude;
                            scene3d.LightRig.Rotation.Longitude = Picture.LightRigLongitude;
                            scene3d.LightRig.Rotation.Revolution = Picture.LightRigRevolution;
                        }

                        pic.ShapeProperties.Append(scene3d);
                    }

                    if (Picture.HasShape3D)
                    {
                        A.Shape3DType shape3d = new A.Shape3DType();

                        if (Picture.HasBevelTop)
                        {
                            shape3d.BevelTop = new A.BevelTop();
                            shape3d.BevelTop.Preset = Picture.BevelTopPreset;
                            shape3d.BevelTop.Width = Picture.BevelTopWidth;
                            shape3d.BevelTop.Height = Picture.BevelTopHeight;
                        }

                        if (Picture.HasBevelBottom)
                        {
                            shape3d.BevelBottom = new A.BevelBottom();
                            shape3d.BevelBottom.Preset = Picture.BevelBottomPreset;
                            shape3d.BevelBottom.Width = Picture.BevelBottomWidth;
                            shape3d.BevelBottom.Height = Picture.BevelBottomHeight;
                        }

                        if (Picture.HasExtrusion)
                        {
                            A.ExtrusionColor extcolor = new A.ExtrusionColor();
                            extcolor.InnerXml = Picture.ExtrusionColorInnerXml;
                            shape3d.ExtrusionColor = extcolor;
                            shape3d.ExtrusionHeight = Picture.ExtrusionHeight;
                        }

                        if (Picture.HasContour)
                        {
                            A.ContourColor contourcolor = new A.ContourColor();
                            contourcolor.InnerXml = Picture.ContourColorInnerXml;
                            shape3d.ContourColor = contourcolor;
                            shape3d.ContourWidth = Picture.ContourWidth;
                        }

                        if (Picture.HasMaterialType)
                        {
                            shape3d.PresetMaterial = Picture.MaterialType;
                        }

                        if (Picture.HasZDistance)
                        {
                            shape3d.Z = Picture.ZDistance;
                        }

                        pic.ShapeProperties.Append(shape3d);
                    }

                    Xdr.ClientData clientdata = new Xdr.ClientData();
                    // the properties are true by default
                    if (!Picture.LockWithSheet) clientdata.LockWithSheet = false;
                    if (!Picture.PrintWithSheet) clientdata.PrintWithSheet = false;

                    if (Picture.UseRelativePositioning)
                    {
                        Xdr.OneCellAnchor ocanchor = new Xdr.OneCellAnchor();
                        ocanchor.FromMarker = new Xdr.FromMarker();
                        // Subtract 1 because picture goes to bottom right corner
                        // Subtracting 1 makes it more intuitive that (1,1) means top-left corner of (1,1)
                        ocanchor.FromMarker.ColumnId = new Xdr.ColumnId() { Text = iColumnId.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.ColumnOffset = new Xdr.ColumnOffset() { Text = lColumnOffset.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.RowId = new Xdr.RowId() { Text = iRowId.ToString(CultureInfo.InvariantCulture) };
                        ocanchor.FromMarker.RowOffset = new Xdr.RowOffset() { Text = lRowOffset.ToString(CultureInfo.InvariantCulture) };

                        ocanchor.Extent = new Xdr.Extent();
                        ocanchor.Extent.Cx = Picture.WidthInEMU;
                        ocanchor.Extent.Cy = Picture.HeightInEMU;

                        ocanchor.Append(pic);
                        ocanchor.Append(clientdata);
                        wsd.Append(ocanchor);
                    }
                    else
                    {
                        Xdr.AbsoluteAnchor absanchor = new Xdr.AbsoluteAnchor();
                        absanchor.Position = new Xdr.Position();
                        absanchor.Position.X = Picture.OffsetX;
                        absanchor.Position.Y = Picture.OffsetY;

                        absanchor.Extent = new Xdr.Extent();
                        absanchor.Extent.Cx = Picture.WidthInEMU;
                        absanchor.Extent.Cy = Picture.HeightInEMU;

                        absanchor.Append(pic);
                        absanchor.Append(clientdata);
                        wsd.Append(absanchor);
                    }

                    wsd.Save(dp);
                }
            }
            #endregion
        }