November Happy Hour will be moved to Thursday December 5th.

Batch Resize

Vote:
 

Hi,

Does ImageVault support batch resize?

I have a set of media ids and corresponding resize parameters which are different for each media id.

Is it possible to get resized urls for whole set of media using just one call to the "Core" using .NET client API?

#90558
Sep 12, 2014 9:38
Vote:
 

Hi!

You can request a number of formats and items and get a resulting matrix of urls for each combination of items and format.

If you have 10 media that should be displayed in 10 different formats and only want to use one core call then the only option is to request the full matrix returning 10x10 results. You can, on the other hand, select to use only the 10 combinations that you requested and the rest of the 90 combinations will not be used.

The actual conversion (read original media, perform conversion, save result to disk) will only be done when accessing the url of the media. So if you only use 10 conversions, the remaining 90 will not be converted.

The example below will request five items and formats and get the correct ones. (Observe that this strategy needs iv 4.4.22 since before that, the order of the resulting conversions was not guaranteed to be the same as the requested one.)

var client = ClientFactory.GetSdkClient();

var mediaService = client.CreateChannel();

//media item ids
var ids = new[] {13301,13300 , 13299, 13298, 13297};

//formats
var formats = new List
{
    new ImageFormat {Effects = {new ResizeEffect(100, 200)}},
    new ImageFormat {Effects = {new ResizeEffect(120, 210,ResizeMode.ScaleToFill)}},
    new WebMediaFormat{Effects = {new ResizeEffect(200,0)}},
    new ThumbnailFormat{Effects = {new ResizeEffect(100, 0)}},
    new ThumbnailFormat{Effects = {new ResizeEffect(30, 30,ResizeMode.ScaleToFill)}}
};
var q = new MediaItemQuery {
    Filter = { Id = ids },
    Populate = { MediaFormats = formats}

};
var mediaItems = mediaService.Find(q);
for (int i = 0; i < ids.length; i++) {     var m =" mediaItems[i];"     var mc =" m.MediaConversions[i];"     console.writeline("media item:"+m.id+" conversion: "+mc.mediaformatid+" url: "+mc.url); }>
#90633
Edited, Sep 15, 2014 12:12
Vote:
 

Great! It works.

Just small typo in 25 line (index should be "0" instead "i").

#90645
Sep 15, 2014 13:46
Vote:
 

Hi!

Actually it should be i. 

If you want first media (13301) with the first format (resize(100,200)) and the second media (13300) with the second format (resize(120,210,...)) then you will need to get that specific format that has the same index as the media...

like

url1 = mediaItems[0].MediaConversions[0];

url2 = mediaItems[1].MediaConversions[1];

aso.

If using 0, you will only get the first format (resize(100,200)) for all media

#90649
Edited, Sep 15, 2014 13:55
Vote:
 

Hi Dan,
Perhaps you will be surprised but MediaConversions[0] works!

May be it is a kind of magic or hidden feature but first element in MediaConversions list is different for medias with different resize formats.
I checked it multiple time in a debugger.

Also I have noted one other surprizing for me but logical thing:
If for example I have 10 images and created 10 formats but these formats are not unique then I will receive only unique MediaConversions, for example only 5.That is why I thought that you made a typo because I received "IndexOutOfBounds" error when tried to get MediaConversions[6] having only 5 unique for 10 images.

#90655
Edited, Sep 15, 2014 14:23
Vote:
 

Hi, 

what version of IV are you using? if you are using a version prior to 4.4.22 then the order is not specified and can be random.

Regarding the filtering of unique formats, thats correct, they will be removed even in 4.5 where they shouldn't, need to post a bug about that.

In the meantime, regardless of what version you are using, you can use the PreparePopulateQuery method to lookup the id of the format and then filter it out afterwards.

The example below request multiple formats that are the same but will use a map to get the correct format.

var client = ClientFactory.GetSdkClient();

var mediaService = client.CreateChannel();

//media item ids
var ids = new[] { 13301, 13300, 13299, 13298, 13297 };

//formats
var formats = new List
{
    new ImageFormat {Effects = {new ResizeEffect(100, 200)}},
    new ImageFormat {Effects = {new ResizeEffect(120, 210,ResizeMode.ScaleToFill)}},
    new WebMediaFormat{Effects = {new ResizeEffect(200,0)}},
    new ImageFormat{Effects = {new ResizeEffect(100, 200)}},//same as the first
    new ImageFormat {Effects = {new ResizeEffect(120, 210,ResizeMode.ScaleToFill)}}, //same as the second
};


var q = new MediaItemQuery {
    Filter = { Id = ids },
    Populate = { MediaFormats = formats }

};
//Creates a map for which media should use which format
var formatMap = new int[ids.Length];
//PreparePopulateQuery will lookup the id of the supplied formats
q.Populate = mediaService.PreparePopulateQuery(q.Populate);
for (int i = 0; i < ids.Length; i++) {
    formatMap[i] = q.Populate.MediaFormats[i].Id;
}

var mediaItems = mediaService.Find(q);
for (int i = 0; i < ids.Length; i++) {
    var m = mediaItems[i];

    Console.WriteLine("Media item:" + m.Id + " conversions: " + m.MediaConversions.Count);
    //Get the media with the correct format using the map
    var mc = m.MediaConversions.FirstOrDefault(x => x.MediaFormatId == formatMap[i]);
    Console.WriteLine("" + mc.MediaFormatId + ", " + mc.GetType().FullName + "," + ((Thumbnail)mc).Width + "x" + ((Thumbnail)mc).Height + ", " + mc.Url);
}
#90657
Sep 15, 2014 14:57
Vote:
 

We use 4.4.12 version. But most probably it will be changed since new version is released.


Thanks for providing workaround! Surely we will use it instead of unspecified behavior .

Very appreciate your quick responses.

#90658
Edited, Sep 15, 2014 15:28
Vote:
 

Just want to add that there is one major assumption in the solution above:
MediaItems in the response should have the same order as corresponding ids in the request.
And the number of mediaItems and ids should be the same what is not always true

for example if a media have been deleted from ImageVault but you still trying to request it by id.

So the last "for" block can be improved in the following way:

            var j = 0;
            for (var i = 0; i < ids.Count; i++)
            {
                if (j >= mediaItems.Count) break;
                var m = mediaItems[j];
                if (m.Id != ids[i]) continue;

                var mc = m.MediaConversions.FirstOrDefault(x => x.MediaFormatId == formatMap[i]);               
                j++;                           
            }
#90739
Sep 17, 2014 9:27
Vote:
 

Good point :)

#90743
Sep 17, 2014 10:45
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.