Replacing images in PPT with byte array from database does not work

Hi @everyone at Syncfusion support,

we have implemented a functionality which recognizes placeholders in image descriptions in powerpoints and replaces those image's data with byte arrays from a db. 

If we replace up to two images per slide, everything is working fine. But if you want to replace two ore more images per slide, all images get replaced by the data of the first image - even though when debugging the backend I see that it should be replaced by the correct image data.

The image replacement is based on  Add and edit images in PowerPoint slides |C# PowerPoint| |Syncfusion|, but the image data is not loaded from FileStream, but from byte array of a database select.

Have you already encountered this behavior and do you have an advice or solution for us to fill in the image data for all pictures correctly?

Greets,

Hendrik


5 Replies

AN Anto Nihil Sahaya Raj Syncfusion Team July 21, 2023 08:32 PM UTC

Hi Hendrik,

We have tried to reproduce the reported problem but it works properly on our end. For your reference, we have attached the sample application which we tried to reproduce the reported problem at our end, and it can be downloaded from the attachment.

Upon further investigation, we suspect that the issue may arise due to the first image's data being only returned from the database when attempting to replace two or more images per slide. So we kindly request you to verify whether the image's data retrieved from the database is correct or not.

If the image's data retrieved from the database is correct,
then could you please modify the attached sample as an issue reproducible sample application and share us. Thereby, we will proceed further to replicate the same problem at our end and will provide you appropriate solution at the earliest.

Note: In the attached sample, we attempted to replace an image using a file stream instead of utilizing image data stored as byte arrays in a database. Because we did not implement separate logic to handle image data from both file streams and databases.


Regards,
Anto Nihil S


Attachment: ReplaceImage_eecf4bad.zip


SS Shmulik Seifer December 12, 2024 05:50 AM UTC

I have the same issue. Other images are also getting updated even if I try to replace one image.

here is the code that I'm using in  C# -



private async Task<IPresentation> ReplaceImagesAsync(IPresentation presentation, CimDocumentPlaceValues documentValues)

        {

            try

            {

                var client = new HttpClient();


                // Cache placeholders and associated image URIs

                var placeholdersWithUris = typeof(CimDocumentPlaceValues)

                    .GetProperties()

                    .Where(prop => prop.PropertyType == typeof(Uri))

                    .Select(prop => new

                    {

                        Placeholder = $"{{{{{prop.Name}}}}}",

                        Uri = prop.GetValue(documentValues)?.ToString()

                    })

                    .Where(item => !string.IsNullOrEmpty(item.Uri))

                    .ToDictionary(item => item.Placeholder, item => new Uri(item.Uri));


                if (!placeholdersWithUris.Any())

                {

                    Console.WriteLine("No valid placeholders with image URIs found.");

                    return presentation;

                }


                // Pre-download image data in parallel

                var imageDataCache = new Dictionary<string, byte[]>();

                var downloadTasks = placeholdersWithUris.Select(async placeholderWithUri =>

                {

                    try

                    {

                        var imageData = await client.GetByteArrayAsync(placeholderWithUri.Value);

                        imageDataCache[placeholderWithUri.Key] = imageData;

                    }

                    catch (Exception ex)

                    {

                        Console.WriteLine($"Failed to download image for placeholder {placeholderWithUri.Key}: {ex.Message}");

                    }

                });


                await Task.WhenAll(downloadTasks);


                // Replace images in slides

                foreach (var slide in presentation.Slides)

                {

                    foreach (var picture in slide.Pictures)

                    {

                        if (!string.IsNullOrEmpty(picture.Title) && imageDataCache.TryGetValue(picture.Title, out var imageData))

                        {

                            try

                            {

                                picture.ImageData = imageData;

                                Console.WriteLine($"Replaced image on slide {slide.SlideNumber}, picture title '{picture.Title}'.");

                            }

                            catch (Exception ex)

                            {

                                Console.WriteLine($"Failed to replace the image on slide {slide.SlideNumber}, picture title '{picture.Title}': {ex.Message}");

                            }

                        }

                    }

                }


                return presentation;

            }

            catch (Exception ex)

            {

                throw new Exception($"Error while replacing placeholders with images: {ex.Message}", ex);

            }

        }



SA Sivakumar Alagusundharam Syncfusion Team December 13, 2024 12:22 PM UTC

Hi Shmulik Seifer,

We have tried to reproduce the reported issue of the “same image replaced for all the images” using the provided code snippet, and it works properly on our end. For your reference, we have attached a simple sample application where we attempted to reproduce the reported problem using your code snippet.

In this sample, we have done the following:

1. Opened the PowerPoint presentation.

2. Retrieved the images from the Data folder and stored them in the “imageDataCache” dictionary.

3. Traversed through the PowerPoint images and replaced the first image in the presentation.

4. Saved the presentation.

We have made further changes related to this kind of issue in our recent development. So, kindly update to the latest version of our NuGet package.

If you are still facing the same issue after trying the above suggestions, please share the following details from your end, which will be helpful to reproduce the exact issue on our side:

1. Input document

2. Images for replacement

3. Complete code snippet or modified sample application to replicate the issue

4. Environment details (Operating system, and if using cloud or Docker, please share configuration and plan details)

5. Product version

6. Output PPTX document generated at your end (this will help us investigate the problem)

We will analyze further and provide you with the appropriate solution at the earliest.


Regards,

Sivakumar. A



Attachment: Sample_d2392d6f.zip


SS Shmulik Seifer December 13, 2024 02:38 PM UTC

Hi Sivakumar. A,


I tried with the updated Nuget package and also tried your sample code but had no success, To be clear in your code you are replacing all the pictures present in the slides but have you tried to replace selected pictures?, like I'm doing. please try to update the selected pictures (by title ) in the ppt file.

Here is my updated code (based on a reference from your code).


 private async Task<IPresentation> ReplaceImagesAsync(IPresentation presentation, CimDocumentPlaceValues documentValues)

        {

            try

            {

                using var client = new HttpClient();


                // Cache placeholders and associated image URIs

                var placeholdersWithUris = typeof(CimDocumentPlaceValues)

                    .GetProperties()

                    .Where(prop => prop.PropertyType == typeof(Uri))

                    .Select(prop => new

                    {

                        Placeholder = $"{{{{{prop.Name}}}}}",

                        Uri = prop.GetValue(documentValues)?.ToString()

                    })

                    .Where(item => !string.IsNullOrEmpty(item.Uri))

                    .ToDictionary(item => item.Placeholder, item => new Uri(item.Uri));


                if (!placeholdersWithUris.Any())

                {

                    Console.WriteLine("No valid placeholders with image URIs found.");

                    return presentation;

                }


                // Pre-download image data in parallel

                var imageDataCache = new Dictionary<string, byte[]>();

                var downloadTasks = placeholdersWithUris.Select(async placeholderWithUri =>

                {

                    try

                    {

                        var imageData = await client.GetByteArrayAsync(placeholderWithUri.Value);

                        lock (imageDataCache)

                        {

                            imageDataCache[placeholderWithUri.Key] = imageData;

                        }

                    }

                    catch (Exception ex)

                    {

                        Console.WriteLine($"Failed to download image for placeholder {placeholderWithUri.Key}: {ex.Message}");

                    }

                });


                await Task.WhenAll(downloadTasks);


                // Replace images in slides

                foreach (var slide in presentation.Slides)

                {

                    foreach (var picture in slide.Pictures)

                    {

                        if (!string.IsNullOrEmpty(picture.Title) && imageDataCache.TryGetValue(picture.Title, out var imageData))

                        {

                            try

                            {

                                picture.ImageData = imageData;

                                Console.WriteLine($"Replaced image on slide {slide.SlideNumber}, picture title '{picture.Title}'.");

                            }

                            catch (Exception ex)

                            {

                                Console.WriteLine($"Failed to replace the image on slide {slide.SlideNumber}, picture title '{picture.Title}': {ex.Message}");

                            }

                        }

                    }

                }


                return presentation;

            }

            catch (Exception ex)

            {

                throw new Exception($"Error while replacing placeholders with images: {ex.Message}", ex);

            }

        }


and please try with this ppt i have (attached below)






SA Sivakumar Alagusundharam Syncfusion Team December 17, 2024 05:34 PM UTC

Shmulik Seifer, we have tried to reproduce the reported issue of the “image not replaced properly with title”using the provided code snippet, and it works properly on our end. For your reference, we have attached a simple sample application where we attempted to reproduce the reported problem using your code snippet. In this sample, we have replaced the image with title in the presentation.

If you are still facing the same issue after trying the above suggestions, please share the following details from your end, which will be helpful to reproduce the exact issue on our side:

1. Input document.

2. Images for replacement.

3. Complete code snippet or modified sample application to replicate the issue.

4. Environment details (Operating system, and if using cloud or Docker, please share configuration and plan details)

5. Product version.

6. Output PPTX document generated at your end (this will help us investigate the problem)


We will analyze further and provide you with the appropriate solution at the earliest.


Regards,

Sivakumar. A



Attachment: Sample_28f8482a.zip

Loader.
Up arrow icon