C# SDK: trying to write a program to get an image URL from a cell

This is a variation of an earlier thread I started C# SDK: trying to write a program to insert an image into a cell. That thread has gotten quite big and this is a somewhat different problem, though related.

I’ve gotten pretty good at this, I know how to use MRI, I understand DrawPages, and I know the peculiarities of “storing” images “in” cells.

What I am trying to do is to get the original source URL for the image. I don’t know if that is even possible. When I insert an image, I am using the XGraphicProvider interface to create an XGraphic which accepts a property named “URL” to specify the image file. However that interface seems to be “one-way” with no way to get the URL back.

As an alternative to getting the name of the original file, I’m ok with getting access to the internal copy of the image. A copy of the original image file is stored with the spreadsheet, but it has a new name. If I unzip an ODS file I can see them. What I can’t do is get the name of, or access, those files.

I’ve been through all the properties of the XGraphic, and of the XShape (Graphic Object Shape), associated with the cell in question, and that are accessed through the spreadsheet’s DrawPage. Nowhere is the internal URL or the original URL of the associated image. I know that at least the internal URL is known because if I right-click on an image in LibreOffice and pick “Edit with External Tool” it opens the image as a file in the Temp folder (with an altogether new name), and subsequently saves in back into the spreadsheet if it is edited.

There is an old SDK method for doing all this that no longer works. There are lots of properties apparently associated with the old method, such as “OriginURL”, “URL”, and “GraphicURL”, but none of them seem to have anything in them.

A note to beginners reading this: the term “URL” doesn’t refer to the common internet meaning of the word, but rather to a specially-formatted file path/name used in the LibreOffice SDK. It is, technically, a URL, but don’t assume that it has something to do with the internet.

Thank you!

I have the same problem now, did you find a solution?

Hi Lynn,

No I never found a solution. I’m not sure the URL is even stored in the shape or graphic. It does have the file name I think.

I had another way to compute the URL because my application stores things in known locations.

Sorry. I hope you can come up with a solution…

-jimc

You’re just gonna have a URL, if you insert the image like link.

If you embed the images in the document they will transfer automatically as part of the document if you move or copy it, or if you send it to someone else. To me, embedding images is best unless your document is static and not shared. There’s also the substantial problem of preserving the state of the image files – if you edit, delete, or move them you will affect the spreadsheet which links to them, perhaps without your realizing it. Since spreadsheets and images are typically being changed all the time, this can be a maintenance nightmare.

Of course embedding the images can make the spreadsheet file huge (though it seems to work fine even when it is well over a GB). It is also slow to save, though probably quicker to load than one with linked images. A spreadsheet with linked images is itself small, but if you include the linked images with it, the whole package is probably bigger than the same spreadsheet with embedded images.

Overall, the idea of linked images seems to me like a maintenance nightmare. There’s probably a reason why LibreOffice defaults to embedded images. I’m sticking with it.

My image-insertion program currently doesn’t update embedded images that are different from the file that they came from, and in fact has no way to know if the image file has changed since it was embedded. This discussion has made me think that I should add an option to the program to reload all the images from their files, which would give a way to “refresh” the embedded images to reflect changes to the files that they originally came from. This would give you the best of both methods.

To summarize:

  1. There are two ways to store inserted images, which you select in the “Insert image…” dialog: a) imbedded images (the default). A copy of the JPG file is stored as part of the spreadsheet. b) linked images. Only a link to the JPG file is stored in the spreadsheet. The JPG file must be present in the link location for the spreadsheet to load correctly.

    Using linked images keeps the spreadsheet file size small, and is appropriate for usage when the environment for the spreadsheet is simple and well controlled. Using embedded images results in large spreadsheet files, but allows for simple copying and sharing of spreadsheets.

  2. If you use embedded images, the original JPG file’s URL is not saved in the spreadsheet. If you embed the image programmatically, you can add a property to “UserDefinedAttributes” containing the URL, as described in Lupp’s post above (or below).

  3. I have posted a sample program “ADDPIX” that adds and updates images in spreadsheets. It lets you have the best of both worlds: embedding images in spreadsheets while allowing you to update the JPG files and then embed the updated files in an existing spreadsheet. ADDPIX is written for a specific application, and you would have to modify it to match your spreadsheet format.

-jimc

Insert a image and try (code in Python):

selection = XSCRIPTCONTEXT.getDocument().CurrentSelection[0]
print(selection.GraphicURL.OriginURL)

Now, insert a new image, but, important, active checkbox Link, and test code again.

I did some experimenting and figured out what you are suggesting.

My images are imbedded in the spreadsheet, not stored as links. So GraphicURL->OriginURL is blank. This is true with images inserted using “Insert->Image…” (without checking “Link”) and with images I insert with my program.

I need images to be stored in the spreadsheet, even though it makes the spreadsheet file huge. I share the spreadsheet with others and can’t easily share it with a directory structure containing my hundreds of images, plus the images and the spreadsheet are both constantly changing and I need a saved spreadsheet to contain a record of things at a point in time. If the images aren’t stored in the spreadsheet things get really messy, hard to manage, and prone to errors.

This thread was started long ago when I was trying to figure out how images were stored and accessed in LibreOffice. I’m way past that now (my image-adding program is working) and I don’t really need to pursue this further, plus I think we’ve covered everything relevant that might be useful to others. I will be posting a sample version of my picture-adding program soon, to help others who might be trying to do similar things.

Thanks for your help. You did make me aware of the “Link” option, which I had missed up till now.

-jimc

I thought of something else that might shed light on this question.

Using the Calc GUI, if you right-click on an inserted image, you get an option “Edit With External Tool”. If you pick this, whatever program is associated with JPG images in Windows will open, with the image loaded.

However, the image file is not the original file specified when the image was inserted (assuming that it was originally inserted without “Link” checked), but rather a temporary file with an arbitrary name. This suggests that the spreadsheet probably doesn’t contain the path to the original file, but does contain the complete contents of the original JPG file.

Which makes sense given that embedding rather than linking to the JPG file is used when the original path is not guaranteed to be valid when the spreadsheet is subsequently loaded, as when the spreadsheet has been emailed to someone else.

-jimc

Yes, when you linking some images to a document, then it is recommended to place the images into the same directory as the document is located, and need to use the “store Relative Hyperlinks” option.
Then you must send the images together with the document and a with a remark: “Save them into same directory.”)

If the image files and the sheets file are part of the same persistent project, you may insert the images as links and do as @Zizi64 suggested.
This will thwart the display as soon as the image file is moved outside the project folder. (You would need to restrict relocation processes to another chunk of user code making sure the image URL in the sheet is adapted correctly. It’s endless.)
There are resons to insert images directly into the displaying file if they aren’t too many or too large ones, and updates to the image-file contents without changing the URL aren’t intended. (File size! Database solutions not discussed here.)
If you simply expect the inserted image (the GraphicObjectShape in fact) to remember the URL from where the image was inserted, you can use the property and service .UserDefinedAttributes of that shape for the purpose.
If there are no conflicts to be expected, you may also (mis)use the .Name property for the file’s URL.

(Like the insertion itself and the fact that cells don’t know which objects are anchored to them - except annotation shapes - all this isn’t specialized to Csharp code! It works with every sufficient bridge to the API.)