Try our conversational search powered by Generative AI!

Image resizing for Optimizely CMS 12 doesn't work

Vote:
 

Hi,

Short info: CMS 12.3, DXP is used (tested on "Integration" only for now), Azure Blob storage is configured.

I am trying to configure PictureRenderer.Optimizely in order to generate <picture> elements. The html looks good, but the image is not resized.

Example of html:

<picture>
<source srcset="/siteassets/test-folder/0101f87e7447b76181127d7a3d66ff66.jpeg?width=400&amp;quality=80 400w, /siteassets/test-folder/0101f87e7447b76181127d7a3d66ff66.jpeg?width=800&amp;quality=80 800w, /siteassets/test-folder/0101f87e7447b76181127d7a3d66ff66.jpeg?width=1040&amp;quality=80 1040w" sizes="(max-width: 640px) 400px, (max-width: 1200px) 800px, 1040px">
<img alt="AltTextImage" src="/siteassets/test-folder/0101f87e7447b76181127d7a3d66ff66.jpeg?width=1040&amp;quality=80" loading="lazy">
</picture>

As I understand the relations of the modules is the following one:

  1. PictureRenderer.Optimizely renders HTML (basing of the Picture profile) and it depends on the module (#2) below
  2. Baaijte.Optimizely.ImageSharp.Web re-uses module #3 for Optimizely. Most of the configuration in Startup.cs is related to this module.
  3. SixLabors.ImageSharp.Web - the module which allows image manipulation via URL based commands.

    My dependencies:



    Part of ConfigureServices method.

    // Azure Blob
    services.AddAzureBlobProvider(options =>
    {
    	options.ConnectionString = _configuration.GetConnectionString("EPiServerAzureBlobs");
    	options.ContainerName = BlobContainerName;
    });
    
    // Configuration of Baaijte.OptimizelyImageSharp.Web
    services.AddImageSharp()
    	.Configure<AzureBlobStorageCacheOptions>(options =>
    	{
    		options.ConnectionString = _configuration.GetConnectionString("EPiServerAzureBlobs");
    		options.ContainerName = BlobContainerName;
    	})
    	.ClearProviders()
    	.AddProvider<BlobImageProvider>()
    	.SetCache<AzureBlobStorageCache>();


    My Configure method (only the last row in the method is related to this task).

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    	/* geta-notfoundhandler begin */
    	app.UseNotFoundHandler();
    	/* geta-notfoundhandler end */
    
    	if (env.IsDevelopment())
    	{
    		app.UseDeveloperExceptionPage();
    	}
    
    	app.UseStaticFiles();
    	app.UseRouting();
    	app.UseAuthentication();
    	app.UseAuthorization();
    
    	app.UseEndpoints(endpoints =>
    	{
    		endpoints.MapContent();
    		endpoints.MapControllers();
    		endpoints.MapRazorPages(); /* required for "geta-notfoundhandler" as well */
    	});
    
    	// Add the image processing middleware.
    	app.UseBaaijteOptimizelyImageSharp();
    }

I looked through example: https://github.com/SixLabors/ImageSharp.Web/blob/main/samples/ImageSharp.Web.Sample/Startup.cs

and tried to add ".AddProcessor<ResizeWebProcessor>()" explicitly, but it didn't help.

It is worth to mention that readme file for module Baaijte.Optimizely.ImageSharp.Web contains statement : DO NOT add other SixLabors.ImageSharp.Web settings!!
So, I haven't tried to use any other options...

Will be glad to know if somebody uses the same modules and has a working configuration. Thank you in advance.

Best regards,

Maxim

#277006
Mar 23, 2022 16:04
Vote:
 

Hi again,

It looks that I found a root cause. Decided to check the example (https://github.com/SixLabors/ImageSharp.Web/blob/main/samples/ImageSharp.Web.Sample/Startup.cs) one more time and found that I have a wrong position of image processing middleware.

So, final version of Configure method is:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	/* geta-notfoundhandler begin */
	app.UseNotFoundHandler();
	/* geta-notfoundhandler end */

	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}

	// Add the image processing middleware.
	app.UseBaaijteOptimizelyImageSharp();

	app.UseStaticFiles();
	app.UseRouting();
	app.UseAuthentication();
	app.UseAuthorization();

	app.UseEndpoints(endpoints =>
	{
		endpoints.MapContent();
		endpoints.MapControllers();
		endpoints.MapRazorPages(); /* required for "geta-notfoundhandler" as well */
	});
}
#277016
Mar 23, 2022 18:32
Vote:
 

Hi Maxim, 

I tried same approach but getting error on DXP. 

Do you have any suggestion how to fix it? - Thanks!

See complete log.

2022-09-01T06:01:08.169154963Z       System.IO.DirectoryNotFoundException: Could not find a part of the path '/app/App_Data/blobs/b9cd4e8815db4dc081fd1fd8bdecd642/77aa03178c234b9fbec92d99e293280b.png'.

2022-09-01T06:01:08.169159863Z          at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)

2022-09-01T06:01:08.169165163Z          at Interop.CheckIo(Error error, String path, Boolean isDirectory, Func`2 errorRewriter)

2022-09-01T06:01:08.169170463Z          at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)

2022-09-01T06:01:08.169175363Z          at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)

2022-09-01T06:01:08.169181063Z          at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)

2022-09-01T06:01:08.169187063Z          at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)

2022-09-01T06:01:08.169209764Z          at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)

2022-09-01T06:01:08.169214864Z          at EPiServer.Framework.Blobs.FileBlob.OpenRead()

2022-09-01T06:01:08.169219364Z          at EPiServer.Framework.Blobs.BlobExtensions.ReadAllBytes(Blob blob)

2022-09-01T06:01:08.169223964Z          at EPiServer.Cms.Shell.UI.Controllers.Internal.ThumbnailController.Generate(ContentReference contentLink)

2022-09-01T06:01:08.169228464Z          at lambda_method893(Closure , Object , Object[] )

2022-09-01T06:01:08.169574768Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)

2022-09-01T06:01:08.169591468Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Logged|12_1(ControllerActionInvoker invoker)

2022-09-01T06:01:08.169617668Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

2022-09-01T06:01:08.169625169Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)

2022-09-01T06:01:08.169630769Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)

2022-09-01T06:01:08.169636769Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()

2022-09-01T06:01:08.169641869Z       --- End of stack trace from previous location ---

2022-09-01T06:01:08.169646069Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

2022-09-01T06:01:08.169650969Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)

2022-09-01T06:01:08.169655269Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)

2022-09-01T06:01:08.169660169Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()

2022-09-01T06:01:08.169664669Z       --- End of stack trace from previous location ---

2022-09-01T06:01:08.169669069Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)

2022-09-01T06:01:08.169673469Z          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)

2022-09-01T06:01:08.169677869Z          at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)

2022-09-01T06:01:08.169682669Z          at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)

2022-09-01T06:01:08.169700669Z          at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)

2022-09-01T06:01:08.169707170Z          at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)

2022-09-01T06:01:08.169713670Z          at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)

2022-09-01T06:01:08.169719170Z          at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

2022-09-01T06:01:08.169725070Z          at SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext httpContext, Boolean retry)

2022-09-01T06:01:08.169730370Z          at EPiServer.Middleware.InitializeOnFirstRequestMiddleware.InvokeAsync(HttpContext httpContext)

2022-09-01T06:01:08.169735770Z          at EPiServer.Framework.DependencyInjection.Internal.VisitorGroupMiddleware.Invoke(HttpContext httpContext)

2022-09-01T06:01:08.169741170Z          at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
#286454
Sep 01, 2022 6:09
Sanjay Kumar - Sep 02, 2022 6:46
@ErikHenningson - Have you faced similar issue on DXP?
Vote:
 

One thing we found was that in addition to adding the app.UseBaaijteOptimizelyImageSharp(); middleware early in the Configure() method, we also had to add services.AddBaaijteOptimizelyImageSharp(); before configuring the blob and caching provider options in the ConfigureServices() method.

#286473
Sep 01, 2022 15:45
Vote:
 

Hi @Daniel

I tried same way, here is the code sample but no luck.

 public void ConfigureServices(IServiceCollection services)
  {
            services.AddBaaijteOptimizelyImageSharp();           
            if (!_webHostingEnvironment.IsDevelopment())
            {
               services.AddCmsCloudPlatformSupport(_configuration);
            }          
            
            services.AddMvc();
            services.AddSite();
            services.AddCms();        
            services.AddImagePointEditor();
            services.AddEmbeddedLocalization<Startup>();
            services.Configure<AppSettings>(_configuration.GetSection("AppSettings"));
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseBaaijteOptimizelyImageSharp();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();     
            app.UseSession();
 }
#286476
Edited, Sep 01, 2022 16:14
Vote:
 

Hi Sanjay. You need have slightly different config when running on you local machine (storing the blobs in the file system) compared to when running in Azure (storing the blobs in Azure storage).
Take a look at the config needed for DXP here: https://github.com/vnbaaij/Baaijte.Optimizely.ImageSharp.Web#configuration-for-use-with-dxp

#286516
Sep 02, 2022 7:05
Sanjay Kumar - Sep 02, 2022 12:56
Hi Erik,
I have configured DXP settings and tried but no luck getting similar error and noticed using DXP setting, when I upload the files in media assets these are not showing in Microsoft Azure Storage Explorer under mysitemedia container.
Erik Henningson - Sep 02, 2022 13:35
Seems to me that your solution isn't properly configured for Azure? Storing the files as blob in a container is standard functionality, and has nothing to do with PictureRenderer or ImageSharp.
Contact support if this is a DXP solution.
Sanjay Kumar - Sep 02, 2022 14:03
But when I roll back BaaijteOptimizelyImageSharp changes then it works and I am able to see images loaded in mysitemedia .
Vote:
 

In the example code for DXP the connection string is being read from the connectionStrings section. However, the connection string for the Azure provider is no where to be found for DXP since it is hidden inside Azure Vaults. Is there any way to reveal it?

.Configure<AzureBlobStorageCacheOptions>(options =>
        {
            options.ConnectionString = _configuration.GetConnectionString("EPiServerAzureBlobs");
            options.ContainerName = "mysitemedia";
        })
#295440
Jan 27, 2023 11:41
Vote:
 

Hi,

I have tried Baaijte.Optimizely.ImageSharp.Web on my current project, image resizing works perfectly fine when view on website, but I noticed images are not resized  when in edit/preview mode, can anyone have any solution for this?

Thanks in Advance!

#296104
Feb 07, 2023 10:28
huseyinerdinc - Feb 07, 2023 10:31
It seems that the query string has two question marks in edit mode. So to add an extra query parameter you may need to check if there is already an existing query parameter and if so, add & instead off ? to the link.
Vote:
 

Hi,

Thanks for the quick reply!

Please ignore the above screen shot, here is the updated one.

#296109
Feb 07, 2023 11:00
Erik Henningson - Feb 08, 2023 16:07
It's not possible to see in the image, but the problem is probably the same as above. In edit mode the CMS adds ?epieditmode=true depending on how you fetch the image url. If you add your own query string you will end up with two query strings.
There are multiple solutions.
You could for example use PictureRenderer instead (https://hacksbyme.net/2022/08/16/optimize-images-on-your-optimizely-cms-site/).
Or not use e.g Html.PropertyFor, but instead add the Editing attributes on surrounding element (an example can be seen in "step 3" in the same blog post,
Malik Kadiwar - Feb 10, 2023 6:21
Thanks Erik for the reply.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.