
Как на JavaScript узнать реальный размер изображения

Как на JavaScript узнать реальный размер изображения
Для работы с масштабированными изображениями в JavaScript или эффектов типа лайтбокса, необходимо знать реальную высоту и ширину изображения. Но в CSS или в атрибутах изображения width и height можно задать любые размеры. Поэтому попытка определить реальный размер из этих атрибутов вернет неправильные значения, свойства ширины и высоты покажут текущие размеры. К счастью, современные браузеры с поддержкой HTML5 позволяют обрабатывать два дополнительных свойства: naturalWidth и naturalHeight, в которых содержатся реальные размеры изображения.
По результатам тестирования выяснено, что эти свойства поддерживаются в Internet Explorer версии 9 и выше, Firefox и других браузеразх на движке Gecko, Chrome и другие браузеры на движке WebKit, в том числе Safari, а также Opera на движке Presto, начиная с версии 10. Для старых браузеров, таких как Internet Explorer 6-8, Opera 9 и ниже, существует хитрый трюк, с помощью которого все-таки можно определить реальные размеры изображения. Для этого создается новое изображение, которому присваивается атрибут src равный проверяемому изображению. После этого атрибуты width и height вновь созданного изображения будут содержать его реальные размеры. Если объединить оба способа, то получится примерно такая функция, как у меня:
Code (HTML) : Убрать нумерацию
- <script type="text/javascript">
- // Функция для получения реального размера изображения
- // На входе: el - элемент DOM, для которого надо получить размеры
- // На выходе: объект {real_width, real_height, client_width, client_height}
- // или false, если произошла ошибка
- function get_dimensions(el) {
- // Браузер с поддержкой naturalWidth/naturalHeight
- if (el.naturalWidth!=undefined) {
- return { 'real_width':el.naturalWidth,
- 'real_height':el.naturalHeight,
- 'client_width':el.width,
- 'client_height':el.height };
- }
- // Устаревший браузер
- else if (el.tagName.toLowerCase()=='img') {
- var img=new Image();
- img.src=el.src;
- var real_w=img.width;
- var real_h=img.height;
- return { 'real_width':real_w,
- 'real_height':real_h,
- 'client_width':el.width,
- 'client_height':el.height };
- }
- // Что-то непонятное
- else {
- return false;
- }
- }
- </script>
Code (HTML) : Убрать нумерацию
- <img id="my_image" src="image.jpg" width="100" height="100" />
- <script type="text/javascript">
- var el=document.getElementById('my_image');
- // Изображение уже загружено или взято из кэша браузера
- if (el.complete) {
- var tmp=get_dimensions(el);
- alert('complete: '+[tmp.real_width, tmp.real_height]);
- }
- // Ожидаем загрузки изображения
- else {
- el.onload=function(event) {
- event=event || window.event;
- var el=event.target || event.srcElement;
- var tmp=get_dimensions(el);
- alert('onload: '+[tmp.real_width, tmp.real_height]);
- }
- }
- </script>
Просмотров: 13613 | Комментариев: 8
Метки: JavaScript

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(16.08.2021 в 16:28):
Если запрошенный элемент не является изображением

Petya
(16.08.2021 в 16:22):
А есть ли какие-то реальные условия (исключая заведомо некорректный вызов), при которых сработает ветка "что-то непонятное"?

ManHunter
(24.10.2016 в 20:51):
Потому что не все браузеры возвращают имя тега в верхнем регистре. Про delete согласен, лишнее.

Mnemonist
(24.10.2016 в 18:58):
Спасибо. Как раз то что искал.
Более компактный вариант:
function getRealSizeImg(img) {
if (img.tagName !== 'IMG') return;
if (img.naturalWidth) {
var width = img.naturalWidth;
var height = img.naturalHeight;
} else {
var helpImg = new Image();
helpImg.src = img.src;
var width = helpImg.width;
var height = helpImg.height;
}
return {
width: width,
height: height,
}
}
- - -
1) client_width/client_height в этой фукнции совершенно не нужны. Функция должна делать только то зачем была написана. То есть реальные размеры. А текущие и так можно без проблем узнать.
2) Зачем такая вложенность условий? Они только читабельность ухуджают
3) В других коментариях спорили о delete/null. Но здесь (как и в 90% случаев) ради оптимизации не нужно писать н delete ни null.
В javascript нет фукнции которая удаляет объект. delete удаляет свойство. null - меняет значение. Но не сам объект.
удаляется только то на что нет никаких ссылок.
Здесь же в любом случае никаких ссылок не сохранится. Фукнция выполнятся - и все. Все что в нем было создано больше недоступно. Его никак нельзя достать. А значит оно больше не нужно, и JavaScript его удалит.
4) Ну и если придираться, то зачем писать так?:
el.tagName.toLowerCase()=='img'
Если можно написать: el.tagName === 'IMG'. Ведь toLowerCase это метод, а на его выполнение нужно время
Более компактный вариант:
function getRealSizeImg(img) {
if (img.tagName !== 'IMG') return;
if (img.naturalWidth) {
var width = img.naturalWidth;
var height = img.naturalHeight;
} else {
var helpImg = new Image();
helpImg.src = img.src;
var width = helpImg.width;
var height = helpImg.height;
}
return {
width: width,
height: height,
}
}
- - -
1) client_width/client_height в этой фукнции совершенно не нужны. Функция должна делать только то зачем была написана. То есть реальные размеры. А текущие и так можно без проблем узнать.
2) Зачем такая вложенность условий? Они только читабельность ухуджают
3) В других коментариях спорили о delete/null. Но здесь (как и в 90% случаев) ради оптимизации не нужно писать н delete ни null.
В javascript нет фукнции которая удаляет объект. delete удаляет свойство. null - меняет значение. Но не сам объект.
удаляется только то на что нет никаких ссылок.
Здесь же в любом случае никаких ссылок не сохранится. Фукнция выполнятся - и все. Все что в нем было создано больше недоступно. Его никак нельзя достать. А значит оно больше не нужно, и JavaScript его удалит.
4) Ну и если придираться, то зачем писать так?:
el.tagName.toLowerCase()=='img'
Если можно написать: el.tagName === 'IMG'. Ведь toLowerCase это метод, а на его выполнение нужно время

ManHunter
(07.09.2015 в 14:00):
delete поддерживается браузерами еще с первого пришествия

Arris
(06.09.2015 в 13:35):
У меня нет уверенности, что delete something будет поддерживаться старыми браузерами так же, как описано в современном стандарте. Впрочем, на этот случай лучше совместить - поставить И delete, И =null.

ManHunter
(03.09.2015 в 07:44):
Не совсем так, конечно, но мысль правильная. За собой надо прибираться, освобождая ресурсы. Подкорректировал, спасибо!

Arris
(03.09.2015 в 03:03):
Отмечу, что первый листинг стоит переписать:
if (el.tagName.toLowerCase()=='img') {
var img=new Image();
img.src=el.src;
var cl_w = el.width, cl_h = el.height;
img = null;
return { 'real_width':img.width,
'real_height':img.height,
'client_width':cl_w,
'client_height':cl_h };
}
Или delete img;
if (el.tagName.toLowerCase()=='img') {
var img=new Image();
img.src=el.src;
var cl_w = el.width, cl_h = el.height;
img = null;
return { 'real_width':img.width,
'real_height':img.height,
'client_width':cl_w,
'client_height':cl_h };
}
Или delete img;

Добавить комментарий
Заполните форму для добавления комментария
