Получить высоту изображения с помощью jQuery из Flickr без загрузки файла изображения? - PullRequest
3 голосов
/ 13 сентября 2011

В настоящее время я работаю над решением jQuery, где я хочу загружать изображения из RSS-канала Flickr.Меня не устраивает размер по умолчанию, который я получаю из фида - я хочу, чтобы загружаемые изображения были равны или превышают height элемента обертки, в котором я их отображаю. (Шириназдесь не проблема.)

Согласно их документации API , Flickr имеет систему размера изображения, которая выглядит следующим образом:

s   small square 75x75
t   thumbnail, 100 on longest side
m   small, 240 on longest side
-   medium, 500 on longest side
z   medium 640, 640 on longest side
b   large, 1024 on longest side*
o   original image, either a jpg, gif or png, depending on source format

* Before May 25th 2010 large photos only exist for very large original images

Это означает, что естьнет гарантированной высоты - мне нужно проверять высоту для каждого изображения, которое я хочу загрузить.Пример: если изображение представляет собой панораму, и я загружаю большой размер, высоты, вероятно, все еще недостаточно для заполнения моего элемента-обертки.Это потому, что самой длинной стороной будет ширина, и она будет 1024.

Чтобы усложнить ситуацию, высота оболочки может изменяться - не динамически после загрузки страницы, а от страницы к странице.На некоторых страницах это 300 пикселей, на других - 100 пикселей и т. Д.

Насколько я понимаю, единственный способ получить высоту файла изображения - это загрузить его.Итак, я написал некоторый рекурсивный код, который загружает изображение, смотрит на его высоту и, если этого недостаточно, снова вызывает себя для загрузки следующего размера.В текущей версии он начинается с наименьшего размера и работает до тех пор, пока не найдет подходящее изображение или максимально возможное изображение.

Вот код:

$.getJSON(ajaxContentURL, function(data) {
        var flickrImages = [];

        // An array of object with data pertaining Flickr's image sizes
        var flickrImageSizes = [{ size: "small square", pixels: 75, letter: "_s" }, 
                                { size: "thumbnail", pixels: 100, letter: "_t" }, 
                                { size: "small", pixels: 240, letter: "_m" }, 
                                { size: "medium", pixels: 500, letter: "" }, 
                                { size: "medium 640", pixels: 640, letter: "_z" }, 
                                { size: "large", pixels: 1024, letter: "_b"}];

        $.each(data.items, function(index, item) {
            flickrImages.push(loadFlickrImage(item, 0));
        });

        function loadFlickrImage(item, sizeIndex) {
            var path = item.media.m;
            var imgSrc = path.replace("_m", flickrImageSizes[sizeIndex].letter);
            var tempImg = $("<img />").attr("src", imgSrc);

            tempImg.load(function() {
               // Is it still smaller? Load next size
               if (this.height < el.data("scrollableAreaHeight")) {
                    // Load a bigger image, if possible
                    if ((sizeIndex + 1) < flickrImageSizes.length) {
                        loadFlickrImage(item, sizeIndex + 1);
                    } else {
                        return this;
                    }
               else {
                    return this;
               }
            });
        }
});

Это немного грубопо краям, но я надеюсь, что вы получите изображение.

Это работает, но это просто кажется расточительным - загружать столько версий изображения, чтобы получить нужный размер?

У вас есть предложения по улучшению?Я думаю, что это должно начаться с квалифицированного предположения, какой может быть лучший размер, и загрузить его первым.Затем он увидит, подходит ли он или слишком мал или слишком велик, и загрузит следующее или предыдущее изображение в размерном масштабе.Таким образом, вы можете уменьшить количество загружаемых изображений, чтобы получить нужный размер.

Еще лучше: есть ли способ узнать размеры изображения без загрузки реальных файлов изображений?Помните, что у меня нет доступа к полному API Flickr - я просто получаю доступ к JSON-ленте, как этот .

Буду признателен за любые отзывы!

Заранее спасибо!

Ответы [ 4 ]

1 голос
/ 20 сентября 2011

Я решил это, сначала сделав квалифицированное предположение о том, какой размер изображения может быть лучшим.Это предположение основано на высоте элемента, в который будут помещены загруженные изображения.Затем я загружаю это правдоподобное изображение размером, чтобы увидеть, достаточно ли оно высокое.Если он выше или равен желаемой высоте, я использую его.В противном случае я загружаю следующий больший размер, проверяю его высоту и так далее.

Хотя это, вероятно, означает, что я буду загружать большее количество изображений по сравнению с первой загрузкой самого большого размера, я думаю, что это дешевле, когда речь идет об общем количестве загруженных килобайт.Некоторые предварительные тесты показывают, что из стандартной подачи 20 изображений Flickr, 1 или 2 изображения необходимо перезагрузить после первой загрузки.

Дайте мне знать, если вы протестируете это решение и в итоге получите другой результат или считаете, что мой подход неверен.Я ищу самое дешевое и лучшее решение.

Вот текущий код, если кому-то интересно:

$.getJSON(flickrJsonUrl, function(data) {
    // small square - size is 75x75
    // thumbnail -> large - size is the longest side
    var flickrImageSizes = [{ size: "small square", pixels: 75, letter: "_s" },
                            { size: "thumbnail", pixels: 100, letter: "_t" },
                            { size: "small", pixels: 240, letter: "_m" },
                            { size: "medium", pixels: 500, letter: "" },
                            { size: "medium 640", pixels: 640, letter: "_z" },
                            { size: "large", pixels: 1024, letter: "_b"}];
    var loadedFlickrImages = [];
    var startingIndex;
    var numberOfFlickrItems = data.items.length;
    var loadedFlickrImagesCounter = 0;

    // Determine a plausible starting value for the image height
    if (el.data("scrollableAreaHeight") <= 75) {
        startingIndex = 0;
    } else if (el.data("scrollableAreaHeight") <= 100) {
        startingIndex = 1;
    } else if (el.data("scrollableAreaHeight") <= 240) {
        startingIndex = 2;
    } else if (el.data("scrollableAreaHeight") <= 500) {
        startingIndex = 3;
    } else if (el.data("scrollableAreaHeight") <= 640) {
        startingIndex = 4;
    } else {
        startingIndex = 5;
    }

    // Put all items from the feed in an array.
    $.each(data.items, function(index, item) {
        loadFlickrImage(item, startingIndex);
    });

    function loadFlickrImage(item, sizeIndex) {
        var path = item.media.m;
        var imgSrc = path.replace("_m", flickrImageSizes[sizeIndex].letter);
        var tempImg = $("<img />").attr("src", imgSrc);

        tempImg.load(function() {
            // Is it still smaller? Load next size
            if (this.height < el.data("scrollableAreaHeight")) {
                // Load a bigger image, if possible
                if ((sizeIndex + 1) < flickrImageSizes.length) {
                    loadFlickrImage(item, sizeIndex + 1);
                } else {
                    addImageToLoadedImages(this);
                }
            } else {
                addImageToLoadedImages(this);
            }

            // Finishing stuff to do when all images have been loaded
            if (loadedFlickrImagesCounter == numberOfFlickrItems) {
                // DO YOUR FINISHING STUFF HERE, LIKE ADDING THE
                // LOADED IMAGES TO YOUR PAGE...
            }

        });
    }


    function addImageToLoadedImages(imageObj) {

         // YOU CAN DO OTHER STUFF HERE, LIKE CALCULATING
         // AND ADDING ADDITIONAL ATTRIBUTES TO THE IMAGE
         // ELEMENT

         // Add the image to the array of loaded images
         loadedFlickrImages.push(imageObj);

         // Increment counter for loaded images
         loadedFlickrImagesCounter++;


    }

});

Я не могу гарантировать, что этот код "скопирован / вставлен готовзапустить ", так как я извлек это из более широкого контекста, но я надеюсь, что вы получите общее представление.

1 голос
/ 15 сентября 2011

Может быть, я неправильно понимаю проблему, но, возможно, установил высоту в html, а затем изменил размер с помощью jquery до максимального оптимального размера? Загрузка самого большого реалистичного размера всех изображений будет пустой тратой, но это лучше, чем загрузка изображения более одного раза.

Для настройки html, если учитывать малейшее возможное изображение, чтобы предотвратить пустое заполнение. И, конечно, установка одного измерения позволила бы другому установить себя. И если обрезка является проблемой, один из способов - установить размер оболочки и переполнение: скрытый.

Для изменения размера jquery, учитывая, что изображения не загружаются мгновенно, есть вероятность, что зритель увидит размер изменения изображения, который не идеален. Если только вы не сохранили их, пока не загрузите, не отмерите их, а затем не отобразите.

0 голосов
/ 22 августа 2012

Если вы сделаете запрос размера изображения в дополнениях, ширина и высота будут возвращены.

Как и url_z Дополнительно:

url_z="...." height_z="427" width_z="640"

ТамВы идете с высотой, без дополнительного запроса, просто чтобы получить размеры один за другим.

В большинстве случаев вам даже не требуется аутентификация.

0 голосов
/ 29 сентября 2011

Вы можете получить размеры изображения, не загружая их, используя API.Вам не нужно проходить аутентификацию с помощью токена, просто зарегистрируйтесь для получения ключа API.Получив ключ, вы можете сделать что-то вроде этого, чтобы просмотреть размеры:

function getFlickrImageSize(photo_id, api_key){
    $.getJSON('http://api.flickr.com/services/rest/?method=' + 'flickr.photos.getsizes&api_key=' + api_key + '&photo_id=' + photo_id + '&format=json&jsoncallback=?',
        function(data){
            mySizeOj = data.sizes.size;
            // and in Firefox you can size the object result like..
            alert(mySizeOj.toSource());
        }
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...