haplokuon / netDxf

.net dxf Reader-Writer
MIT License
993 stars 403 forks source link

How to create an image with relative path #130

Open lijiayi0921 opened 5 years ago

lijiayi0921 commented 5 years ago

I am trying to add an image with relative path with netDxf. However it seems impossible to create an ImageDefinition in this way, since in the ctor it says "Image file not found". And I cannot modify the "File" field afterwards. What's the best workaround for this ? Thank you

haplokuon commented 5 years ago

I cannot see any problems passing a relative path to the ImageDefinition constructor. It would have been a lot more useful if you would have shown what your actual code looks like.

lijiayi0921 commented 5 years ago

@haplokuon

Thank your for your reply. I am using netDXF 2.2.0.1 from NuGet. Here is my code : ImageDefinition imageDefinition = new ImageDefinition(imageName, imageFile); If I define imageFile as @".\XREF\xxx.jpg", where XREF foldler is located besides the target dxf doc, it gives the following error : System.IO.FileNotFoundException: 'Image file not found'

haplokuon commented 5 years ago

Now I understand your issue, there is no such thing as too much information, the evil is in the details.

There are two main types of constructors for the ImageDefinition. The generic one that besides needing the name and the file of the image, it requires the dimensions, the resolution, and the units. These constructors will not check if the image actually exists since all information required by the image definition is already passed in the constructor.

On the other hand the two other simplified constructors that only require the name and the file, needs to find the image in order to get the rest of the data. When you initialize an ImageDefinition it does not know anything about the future location of the DXF, but it still needs to find the image file. If a relative path is used it will look for it following the actual System.Environment.CurrentDirectory, therefore you will need to set this variable to where you are planning to save the DXF, before creating a new ImageDefinition.

Choose one of the two options.

lijiayi0921 commented 5 years ago

Hi haplokuon, Thank you for your explanation. The second option suits better in my case since I need the basic information of the given image to fit it into my display zone. I will try it next Monday and let you know if everything works fine.

lijiayi0921 commented 5 years ago

Hi @haplokuon , I am experiencing some new problem. With your suggestion No. 1 (relative path with System.Environment.CurrentDirectory), the ImageDefinition and Image are successfully created, and DXF well generated.

How ever when opened in AutoCAD (2017 and 2019), the image content is not shown. Only the frame is shown: image

With image Misc information like this image

In the "xref" dialog, images are shown as "unreadable". If I make the path "absolute", image is loaded. If I then change it back to "relative", image is still fine. Meanwhile the "Saved Path" and other properties remain identical to when it was unreadable. image

More strangly, even if the image is marked "unreadable", in the Brightness/Contrast/Fade dialog, the preview is fine. image.

The same dxf works perectly in MicroStation.

Do you have any idea about how to solve this ? Thank you in advance.

Jiayi

haplokuon commented 5 years ago

I am aware of this issue, and I cannot do anything about it. It seems that AutoCAD doesn't like relative paths when inserting an image in a drawing. However, it has an easy workaround, in AutoCAD go to the "External References Palette" and "Reload All References", the images should show up, it knows where to find the files but for some reason they do not appear. It looks like one of those everlasting bugs in AutoCAD, that they never bothered to fix.

lijiayi0921 commented 5 years ago

Thank you for the workaround! Cheers

philippebedard2 commented 3 years ago

Hi, Sorry to open this thread again. I faced the same issue with Relatives path.

I got an answer from AutoCAD staff that could help you face the problem. It seem like the images should be embedded in the DXF. At the moment, is it possible to do it with netdxf?

I have tested directly on Autocad and using the Picture (Device Independent Bitmap) seem to work fine

Here's the reply from the autocad support

When including an image with a DXF export, it should not be an xref - it needs to be embedded or set as an OLE object. Can you review this AKN article and associated links, and see if these changes help you get this to work for you.

https://knowledge.autodesk.com/support/autocad/...

https://autocadtips1.com/2013/02/22/embed-a-pic...

https://gis.stackexchange.com/questions/97455/c...

If needed, I can also escalate this to an Autodesk agent that can call you and remote into your system to review - but let's see if we can solve the issue here first.

https://gis.stackexchange.com/questions/97455/can-a-dxf-file-contain-raster-images-tiff-jpg

haplokuon commented 3 years ago

No, the suggestion by that, "Autodesk expert", will not solve a thing. He is actually changing the subject, I do not know if it is by ignorance, or because he does not want to actually address this problem, or both. Geez! Everybody is called an expert nowadays.

Without going into the inner workings of the DXF, an IMAGE entity is an externally linked bitmap that, through the IMAGEDEF object, should be able to handle both relative and absolute paths, without sweating. The affirmation that David B. does "When including an image with a DXF export, it should not be an xref - it needs to be embedded or set as an OLE object." IS completely WRONG, it doesn't mean that you cannot do it but there is no need to, external references (xref) SHOULD work.

An OLE object is a different kind of beast with a much broader application than the IMAGE entity, OLEs have been around since the dawn of Windows. In the DXF format there are two entities to handle embedded stuff, they are called OLEFRAME and OLE2FRAME. Not implemented in netDxf and most probably never will, if you wonder. We are talking here, about an IMAGE entity not an OLE object. The DXF is perfectly capable to handle externally linked images, so it is false that an image should be embedded into the DXF. Funny thing is that only relative paths show this issue but not absolute ones. Only AutoCad complains about image relative paths, all other programs I tried that support images, obviously, like their very own Autodesk DWG TrueViewer, does not show this issue. Other externally linked stuff like the underlays (DGN, DWF, and PDF) work fine with relative paths. This is a bug in AutoCad for who knows how long, and don't let anyone convince you otherwise.

The DXF served its purpose 30 years ago but, now, with all that questionable stuff that has been added to AutoCad, it has become a completely blotted and disorganized mess. Autodesk does not care a bit about the DXF, even if it stands for drawing exchange format, you just need to look at the official documentation about the format, it is little more than a table of contents. Better I stop the rant or it will go on forever. Oh, and, how on earth they call the DXF "Drawing eXchange Format" when it can actually contains encoded proprietary data? This is inexcusable. AutoCad is old, very old, and it shows its age, under all its makeup and skin tightening their wrinkles show up when you start to rub a little bit. And I am starting to rant again but I need to get it off my chest.

philippebedard2 commented 3 years ago

Thanks a lot for your reply @haplokuon I will honestly forward that answer and keep you aware of the result. (I might censor some part of it just to make sure to have an answer from the guy, took me around 2 weeks to finally get in touch with someone that might be able to solve that situation) or at least try

haplokuon commented 2 years ago

Despite what I said in my previous post the Autodesk DWG TrueViewer seems to suffer this same problem sometimes, what seems more normal since, I guess, it shares code from AutoCad. If the folder where the images are stored is added to the Support File Search Path in the Options, looks like the program knows how to find them. At the moment I only tried when in the field where the information of the file path is stored only appears the file name plus its extension with no folder path. I will try other options another day.