problem when getxaml

20 views
Skip to first unread message

Wpf Help

unread,
Apr 13, 2009, 3:03:36 AM4/13/09
to WPF Graphics Site group
when i try to get the xaml of read svg file it will give null
imagesource

Andrej Benedik

unread,
Apr 14, 2009, 2:58:03 AM4/14/09
to wpf-gr...@googlegroups.com
The GetXaml method cannot know the image file name and its path - the method does not save the images, it just gets the xaml text. To solve this it is possible to set a ResolveImagePath delegate to the BaseXamlWriterSettings class that can be passed to the GetXaml method. The ResolveImagePath  delegate gets the BitmapSource and returns the file name that will be written in the xaml. Without this method the BitmapImage is not created in xaml.

The following source code does the trick. It reads the svg file. Than saves all the images to the disk and saved the file names. Than the GetXaml is called with the ResolveImagePath delegate set that resolved the image paths from the dictionary.

        private Dictionary<BitmapSource, string> _imageFileNames;

        private string GetXaml(string svgFileName, string imagesPath, string imageFormatString)
        {
            string xamlText;
            Ab2d.ReaderSvg myReaderSvg;
            Ab2d.Common.ReaderSvg.WpfXamlWriterSettings xamlSettings;
           

            // Read the svg file
            myReaderSvg = new Ab2d.ReaderSvg();
            myReaderSvg.Read(svgFileName);


            _imageFileNames = new Dictionary<BitmapSource, string>();

            // Save the images (if any) and fill the _imageFileNames dictionary with file names
            for (int i = 0; i < myReaderSvg.BitmapImages.Count; i++)
            {
                BitmapSource oneBitmap;
                string filePath;

                oneBitmap = myReaderSvg.BitmapImages[i];
                filePath = System.IO.Path.Combine(imagesPath, string.Format(imageFormatString, i + 1));

                using (System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
                {
                    PngBitmapEncoder enc = new PngBitmapEncoder();

                    // NOTE:
                    // If break on exception is turned on in VS,
                    // the next line will throw an exception, but it is handled in .net framework (so click continue)
                    // See also: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9f23dde5-f281-4175-a6a2-5f4ad14a4dfe/?lc=1033&ffpr=0
                    enc.Frames.Add(BitmapFrame.Create(oneBitmap));
                    enc.Save(fs);

                    _imageFileNames.Add(oneBitmap, filePath);
                }
            }


            xamlSettings = new Ab2d.Common.ReaderSvg.WpfXamlWriterSettings();
            xamlSettings.ResolveImagePath = ResolveImagePath;

            xamlText = myReaderSvg.GetXaml(xamlSettings);

            return xamlText;
        }

        private string ResolveImagePath(BitmapSource imageToResolve)
        {
            string retImagePath;

            if (imageToResolve == null)
                retImagePath = "";
            else
                _imageFileNames.TryGetValue(imageToResolve, out retImagePath);

            return retImagePath;
        }


The code can be tested with:
string xamlText = GetXaml("images_test.svg", @"c:\temp\", "image_{0}.png");


Andrej

Wpf Help

unread,
Apr 14, 2009, 5:21:19 AM4/14/09
to WPF Graphics Site group
Hi,

Another problem occur is always get as streamgeometry but i want as
pathgeometry
i just set this myReaderSvg.ReadPathAsPathGeometry = true; but always
get as streamgeometry
>                     // See also:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9f23dde5-f28...
>                     enc.Frames.Add(BitmapFrame.Create(oneBitmap));
>                     enc.Save(fs);
>
>                     _imageFileNames.Add(oneBitmap, filePath);
>                 }
>             }
>
>             xamlSettings = new
> Ab2d.Common.ReaderSvg.WpfXamlWriterSettings();
>             xamlSettings.ResolveImagePath = ResolveImagePath;
>
>             xamlText = myReaderSvg.GetXaml(xamlSettings);
>
>             return xamlText;
>         }
>
>         private string ResolveImagePath(BitmapSource imageToResolve)
>         {
>             string retImagePath;
>
>             if (imageToResolve == null)
>                 retImagePath = "";
>             else
>                 _imageFileNames.TryGetValue(imageToResolve, out
> retImagePath);
>
>             return retImagePath;
>         }
>
> The code can be tested with:
> string xamlText = GetXaml("images_test.svg", @"c:\temp\", "image_{0}.png");
>
> Andrej
>

Andrej Benedik

unread,
Apr 14, 2009, 8:15:55 AM4/14/09
to wpf-gr...@googlegroups.com
I have checked the ReadPathAsPathGeometry property again and it works correcty.

But this works only when you read the file with ReaderSvg and not with the exported xaml.
Also you need to set ReadPathAsPathGeometry to true BEFORE reading the svg file.

So the Viewbox that is returned with the Read method (if ReadPathAsPathGeometry is set to true) will contain PathGeometries and not StreamGeometries.

But if you call GetXaml, the returned xaml will define all paths as <Path Data="..." - if this xaml text is than read by the WPF the path is read as StreamGeometry. The WPF's XamlWriter also writes the Path the same way.

I would be possible to manually write the Path as PathFigureCollection, but this would be quite a change for my XamlWriter. Maybe this could be added into one of the next releases.


It is still possible that my test for ReadPathAsPathGeometry property is not perfect. So if you do not get the PathGeometry in the read Viewbox (with setting ReadPathAsPathGeometry to true), please add a file to the news group so I can check it with your file.

Andrej

Wpfhelp

unread,
Apr 14, 2009, 8:38:28 AM4/14/09
to wpf-gr...@googlegroups.com
Try this


            string xamlText;
            Ab2d.ReaderSvg myReaderSvg;
            string svgFileName = "images_test.svg";

            myReaderSvg = new Ab2d.ReaderSvg();
            myReaderSvg.ReadPathAsPathGeometry = true;
            myReaderSvg.Read(svgFileName);

            xamlText = myReaderSvg.GetXaml();//will return stream geometry

but i need pathgeometry

Thanks

Andrej Benedik

unread,
Apr 14, 2009, 8:53:13 AM4/14/09
to wpf-gr...@googlegroups.com
As I have already sad - the myReaderSvg.Read returns the Viewbox that has PathGeometry, but the xaml that is returned by GetXaml will define all Paths as <Path Data="..." that is parsed by WPF as StreamGeometry.

So if you need PathGeometry you will have to use ReaderSvg - it is not possible to get PathGeometry from the produced xaml.

I know the GetXaml method is not perfect, but it is much better than not having it (as in previous version) and use the WPF's XamlWriter that is useless in 80% of cases.

This is the actual code that I use to test the ReadPathAsPathGeometry  property. Below is the sample svg file.

        [Test]
        public void ReadPathAsPathGeometryTest()
        {
            Viewbox testViewbox;
            Ab2d.ReaderSvg testReaderSvg;
            System.Windows.Shapes.Path firstPath;
            string fileName;

            fileName = GetTestFullFileName("my_flower.svg");

            testReaderSvg = new Ab2d.ReaderSvg();

            // default:
            //testReaderSvg.ReadPathAsPathGeometry = false;

            testViewbox = testReaderSvg.Read(fileName);
            firstPath = ((System.Windows.Controls.Canvas)(((System.Windows.Controls.Canvas)(((System.Windows.Controls.Canvas)(testViewbox.Child)).Children[0])).Children[1])).Children[0] as System.Windows.Shapes.Path;

            Assert.IsTrue((firstPath.Data is System.Windows.Media.StreamGeometry), "ReadPathAsPathGeometry = false: firstPath.Data not StreamGeometry!");

            // set ReadPathAsPathGeometry = true;
            testReaderSvg.ReadPathAsPathGeometry = true;
            testViewbox = testReaderSvg.Read(fileName);
            firstPath = ((System.Windows.Controls.Canvas)(((System.Windows.Controls.Canvas)(((System.Windows.Controls.Canvas)(testViewbox.Child)).Children[0])).Children[1])).Children[0] as System.Windows.Shapes.Path;

            Assert.IsTrue((firstPath.Data is System.Windows.Media.PathGeometry), "ReadPathAsPathGeometry = true: firstPath.Data not PathGeometry!");
        }



<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_svg "http://www.w3.org/2000/svg">
    <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg  version="1.1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="361" height="336" viewBox="0 0 361 336"
     overflow="visible" enable-background="new 0 0 361 336" xml:space="preserve">
<g id="Layer_2">
    <rect x="0.5" y="0.5" fill="#00A0C6" stroke="#71A3CC" width="360" height="335"/>
</g>
<g id="Layer_1">
    <path fill="#FFFFFF" stroke="#000000" d="M184.571,94.848c7.98-1.378,31.817-31.869,42.871-20.767
        c6.926,6.957-1.848,20.605-5.112,26.838c11.657-4.098,38.514-5.76,41.301,9.026c2.406,12.766-9.263,17.353-20.097,16.866
        c4.639,5.106,11.585,7.435,14.208,15.254c2.135,6.366,3.662,23.554-2.337,28.336c-10.297,8.209-25.099-1.318-31.454-9.564
        c0.229,13.991-3.318,26.114-19.434,29.277c-13.128,2.577-24.89-7.365-23.854-20.799c-14.034,10.547-35.176,36.956-48.896,14.945
        c-7.719-12.383-7.054-29.245,7.45-33.619c-11.562-4.83-31.747-3.836-34.965-19.721c-3.651-18.026,22.259-14.507,33.183-11.949
        c1.13-11.899-19.356-53.61,5.563-50.823C165.07,70.618,175,96.5,184.571,94.848z"/>
    <path fill="#FFFF00" stroke="#000000" d="M164.5,138c-24.5-35,40.827-37.726,41.345-11.324c0.842,42.97-44.178,7.963-40.675,12.053
        L164.5,138z"/>
    <path fill="#307C1F" stroke="#000000" d="M218.5,181.5c1.218,5.095,5.105,10.965,7.587,15.477
        c3.967,7.211,8.795,13.624,13.3,20.536c8.889,13.637,20.17,26.876,25.527,42.124c5.028,14.312,4.585,29.683,4.585,44.986
        c0,9.871,0.599,20.098,0.424,29.801c-2.569,0.13-8.054,1.184-8.924-1.424h-0.5c-0.565-7.235-0.095-14.484-0.488-21.74
        c-1.086-20.01-11.136-39.996-17.4-58.747c-5.023-15.036-10.438-28.501-17.988-41.961c-3.964-7.067-11.438-14.809-11.123-23.052
        L218.5,181.5z"/>
</g>
</svg>


Andrej

Wpfhelp

unread,
Apr 14, 2009, 11:53:36 PM4/14/09
to wpf-gr...@googlegroups.com
Hi,

please make an update in ReaderSvg we r waiting

Thanks
Reply all
Reply to author
Forward
0 new messages