6

I have an issue where our custom pipeline which crops images is not running correctly for some images. It was working fine and still seems to work correctly for the existing images but for new images it no longer works correctly.

These are the parameters we are sending to fire our pipeline:

/-/media/test-image.jpg?mw=660&mh=530&as=1&centercrop=1

It is not cropping new images anymore and if I look at the error in the logs this seems to be falling back to the out of the box image pipeline:

14028 16:47:19 ERROR Could not run the 'getMediaStream' pipeline for '/sitecore/media library/test-image'. Original media data will be used. Exception: System.ArgumentException Message: Parameter is not valid. Source: System.Drawing at System.Drawing.Bitmap..ctor(Stream stream) at Sitecore.Resources.Media.SaveColorProfileProcessor.Process(GetMediaStreamPipelineArgs args) at (Object , Object[] ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Resources.Media.Media.GetStreamFromPipeline(MediaOptions options, Boolean& canBeCached)

I've looked into it and thought it might be this bug, but it's for an older version of Sitecore:

https://kb.sitecore.net/articles/856744

More info here:

https://sitecorebasics.wordpress.com/2015/11/21/could-not-run-the-getmediastream-pipeline/

I've also checked the permissions on the images and they seem fine and this issue seems to affect all image types, jpeg, gif, pn etc so I'm a bit stumped what might be causing it.

Other details: We are Running Sitecore 8.1 - update 2.

--Update--

I've taken a copy of the SaveColorProfileProcessor Pipeline and it is indeed throwing an error when trying to read the properties of the image. I've wrapped it in a try{}catch{} and this is skips over the error and proceeds as expected with other Pipelines and resizes the images correctly. I have opened a ticket with Sitecore Support regarding this and why GetMediaStream() is returning this error:

'mediaStream.ReadTimeout' threw an exception of type 'System.InvalidOperationException'

I'll update here further once I know more.

            try
            {
                PropertyItem propertyItem =
                    ((IEnumerable<PropertyItem>) new Bitmap(mediaStream).PropertyItems)
                        .SingleOrDefault<PropertyItem>((Func<PropertyItem, bool>) (x => x.Id == 34675));
                if (propertyItem == null)
                    return;
                args.CustomData.Add("ColorProfile", (object) propertyItem);
            }
            catch (Exception ex)
            {
                Log.Error("Error saving colour profile: " + ex.Message, ex);
                return;
            }
11
  • Do you have Dianoga (Image Compression) installed on your instance?
    – Richard Seal
    Commented Oct 21, 2016 at 16:05
  • No I don't believe so Richard - I did read this post about that too: stackoverflow.com/questions/27952875/…. Commented Oct 21, 2016 at 16:08
  • Looks like you have some custom parameters there as=1&centercrop=1 - have you tried without those?
    – Richard Seal
    Commented Oct 21, 2016 at 16:10
  • Yeah those are required by our pipeline to do the center crop. However If I remove these then I still get the same error in the logs. Oddly if I save down one of the old images where this does work still and re-upload it then I get the same problem so I don't think it's the image or pipleline that is the problem but something else effecting new images, perhaps during upload? Commented Oct 21, 2016 at 16:17
  • 2
    Could you try flipping your app-pool and deleting everything in /App_Data/MediaCache? - edit: Will not fix the issue, but will provide a further clue as to where to look
    – Mark Cassidy
    Commented Oct 21, 2016 at 16:32

2 Answers 2

5

That processor; the Sitecore.Resources.Media.SaveColorProfileProcessor seems bugged to me. I know that's not entirely constructive, but I'll exemplify why I believe this to be.

Your query string contains resizing information. This processor is then tasked with grabbing the color profile for use in resizing later on. In doing this, it opens up a Stream.

enter image description here

Which takes you here:

enter image description here

And ultimately here.

enter image description here

Now here's the thing. From what I can tell; if your media item isn't in the MediaCache at this point; this method will run the <getMediaStream> pipeline again to get the stream.

And I'm guessing this blows up, as you probably cannot open the Stream twice or some such.

5
  • That's where I'd go to also - seems to be able to get in an endless loop
    – Richard Seal
    Commented Oct 21, 2016 at 16:47
  • The error seems to be because its returning a null from that args.MediaData.MediaItem.GetMediaStream and then passing that into the Bitmap constructor - it does look like a weird bit of code!
    – Richard Seal
    Commented Oct 21, 2016 at 16:52
  • That could be of course. Possible if this code returns null. Sitecore.Resources.Media.Media media = MediaManager.GetMedia(new MediaUri(this.InnerItem)); if (media == null) return (Stream) null;
    – Mark Cassidy
    Commented Oct 21, 2016 at 16:56
  • Thanks for this info. This does indeed seem to be the culptit. I've updated my question above to explain what I've done so far to work around this. Commented Oct 24, 2016 at 11:34
  • I found some discussions on this on SO. stackoverflow.com/questions/15571022/… - it could be related. Generally; perhaps meta data on your images is incompatible with the default GDI library.
    – Mark Cassidy
    Commented Oct 24, 2016 at 11:38
3

Coming back to this after implementing a solution. In the end I had to write a custom pipeline to replace the out of the box one and wrap the call to GetMediaStream as suggested by Mark & Rich.

I'm still waiting for Sitecore support to come back to me on this and let me know if there is a better solution.

Here is the code in case anyone else needs to do this:

public class CustomSaveColorProfileProcessor
{
    public void Process(GetMediaStreamPipelineArgs args)
    {
        Assert.ArgumentNotNull((object)args, "args");

        var imageIsInvalidForProcessing = !args.MediaData.MimeType.StartsWith("image/", StringComparison.Ordinal) 
                 || !args.Options.GetTransformationOptions().ContainsResizing() 
                 || MediaManager.Config.GetImageFormat(args.MediaData.Extension, (ImageFormat)null) == null;

        if (imageIsInvalidForProcessing) return;

        using (Stream mediaStream = args.MediaData.MediaItem.GetMediaStream())
        {
            try
            {
                PropertyItem propertyItem =
                    ((IEnumerable<PropertyItem>) new Bitmap(mediaStream).PropertyItems)
                        .SingleOrDefault<PropertyItem>((Func<PropertyItem, bool>) (x => x.Id == 34675));
                if (propertyItem == null)
                    return;
                args.CustomData.Add("ColorProfile", (object) propertyItem);
            }
            catch (Exception ex)
            {
                Log.Error("Error saving colour profile: " + ex.Message, ex);
                return;
            }
        }
    }
}

I then patched it in-place of the out of the box one like so:

<getMediaStream>
            <processor type="Custom.Sitecore.Extensions.Pipelines.CustomSaveColorProfileProcessor, Custom.Sitecore.Extensions"
                                         patch:instead="processor[@type='Sitecore.Resources.Media.SaveColorProfileProcessor, Sitecore.Kernel']"/>
</getMediaStream>
4
  • Hey, did you get a fix for this issue from the Sitecore Support? Commented Jan 12, 2017 at 8:25
  • I'm afraid I didn't @PascalMathys as they couldn't replicate this on an out the box install unfortunately. I'm not sure what is causing it but this seems to resolve the problem. Commented Jan 16, 2017 at 14:57
  • FYI looks like this fix is in Sitecore.Kernel since Sitecore 9 (maybe 8.2.5+ too although its a bit different) Commented Feb 16, 2020 at 23:50
  • @AdamSeabridge - Was the cropping done as part of the CropProcessor in AdvanceImage Module. I am getting the same issue , but resulting in SQL Connection Pool Issue Message: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
    – Abhay Dhar
    Commented Dec 21, 2021 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.