Если вы начинаете создавать свой сайт или редактируете одну из страничек своего будущего сайта, то вам будет полезно знать, что размещение картинок возможно не только через обычную ссылку, которая будет иметь формат http:// ваш сайт /upload/картинка.jpg, но и посредством html-ссылки на картинку. Если вам интересно узнать, как будет выглядеть можно попробовать сделать ссылку самостоятельно или подглядеть ее на другом сайте и сделать похожую.
Вам понадобится
- Программное обеспечение Adobe Dreamweaver.
Инструкция
Самый простой способ узнать код картинки – это просмотреть ее код. Для просмотра кода картинки достаточно воспользоваться любым интернет-браузером. Откройте любой сайт, выберите картинку. При нажатии правой кнопкой мыши на этой картинке, можно узнать ее код – выберите пункт контекстного меню «Просмотреть код элемента». В зависимости от браузера, этот пункт меню может звучать по-разному. Откроется небольшое окно, которое подсветит строчку с html-ссылкой изображения. К примеру, . Можно увидеть, что стандартная ссылка от html-ссылки значительно отличается, но путь до картинки остается прежним.
Чтобы поставить на страницу сайта html-ссылку на картинку, необходимо скопировать ссылку, которая была расписана выше, заменить все значения и опубликовать на своей страничке. В html-ссылке вам останется поменять только значение, которое находится между кавычек. Для быстрого создания ссылок без использования копирования-вставки, можно задействовать любую программу html-верстки, например, Adobe Dreamweaver.
После запуска программы, создайте новый проект. В визуальном редакторе введите ссылку на вашу картинку. Нажмите вкладку HTML. Перед вами появится содержимое прошлого окна, только в другом виде, ваша ссылка преобразовалась в html-код.
Тот же результат можно сделать в любом html-редакторе. В социальной сети «Мой мир» у каждого пользователя есть свой блог. Перейдите в этот блог, нажмите добавить запись, добавьте ссылку в визуальный редактор, затем перейдите в редактор html. Вы получите ссылку на языке html.
Источники:
- как получить html-код для картинки
Войти на сайт
или
Забыли пароль?
Еще не зарегистрированы?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Рассказываю о двух способах, которые помогут Вам найти код фотографии или любого другого изображения на фотостоке ShutterStock.
✅ Вариант 1. Откройте фото на отдельной странице, номер будет сразу под фотографией
Под фото будет текст, который содержит номер изображения:
Если вы открываете Шаттерсток на русском языке:
- Код стоковой фотографии без лицензионных платежей: 1091465489
Если вы открываете Шаттерсток на английском языке:
- Royalty-free stock photo ID: 1091465489
Номер изображения в моем примере – это цифры 1091465489.
Не важно, на каком языке этот текст, хоть на китайском, номер фото будет в конце строчки текста, которая находится СРАЗУ под фотографией.
✅ Вариант 2. Посмотрите номер фото в строке браузера
Это второй вариант для тех, кто знает, что такое браузер и где у него строка. Если вам смешно от такого описания, то представьте, есть люди, которые и правда этого не знают. Им хватит Варианта 1)
В общем, если вы знаете, где у браузера строка, поставьте курсор в эту самую строку и перейдите в ее конец – там также будет номер фотографии на Шатерсток.
Перейдите на ShutterStock, чтобы проверить, как это работает.
Ссылка на фотографию из моего портфолио, которую я использовала в примере.
🔻 🔻 🔻
Регистрируйтесь на Шатерсток
как автор фотографий, выкладывайте свои фотографии и зарабатывайте на них! Подписывайтесь на канал и читайте другие статьи по теме заработка на фотостоках:
Подписывайтесь на канал, чтобы не пропустить новые статьи 💖
Если вдруг что-то непонятно или есть другие вопросы – пишите в комментариях. Отвечу 😘
🔻 🔻 🔻
{“activeUser”:{},”journalUser”:{},”request”:{“url”:”/ssi/top/menu?section=groups&position=fixed&game_day=&promo_logo=&isHideNav=&is_game_client=”,”path”:”/ssi/top/menu”,”get”:{“section”:”groups”,”position”:”fixed”,”game_day”:””,”promo_logo”:””,”isHideNav”:””,”is_game_client”:””},”params”:{},”query”:{“section”:”groups”,”position”:”fixed”,”game_day”:””,”promo_logo”:””,”isHideNav”:””,”is_game_client”:””}},”css”:[],”js”:[],”hosts”:{“main”:”my.mail.ru”,”mobile”:”https://m.my.mail.ru”,”gifts”:”//my1.imgsmail.ru/mail/ru/images/my/gifts/”,”content”:”//content.foto.my.mail.ru”,”staticJs”:”//my4.imgsmail.ru/mail/ru/images/js/myjs/mm/out/”,”staticCss”:”//my2.imgsmail.ru/mail/ru/css/new/”,”compass”:”//my3.imgsmail.ru/mail/ru/images/my/compass/static/”,”isNotJsUrlPostfix”:true},”pageTitle”:null,”routes”:[{“key”:”/video/?”,”route”:”pages/video/main/VideoMainPage”},{“key”:”/video/channels/?”,”route”:”pages/video/channels/VideoChannelsPage”},{“key”:”/video/channels/:category/?”,”route”:”pages/video/channels/VideoChannelsPage”},{“key”:”/:domain/:user/video/?”,”route”:”pages/video/user/main/VideoUserMainPage”},{“key”:”/:domain/:user/video/:album/?”,”route”:”pages/video/user/main/VideoUserMainPage”},{“key”:”/v/:user/?”,”route”:”pages/video/user/main/VideoUserMainPage”},{“key”:”/:domain/:user/video-follows/?”,”route”:”pages/video/user/follows/VideoUserFollowsPage”},{“key”:”/:domain/:user/video-followers/?”,”route”:”pages/video/user/followers/VideoUserFollowersPage”},{“key”:”/video/friends/?”,”route”:”pages/video/friends/VideoFriendsPage”},{“key”:”/video/friends/search/:query/?”,”route”:”pages/video/search-friends/VideoSearchFriendsPage”},{“key”:”/video/search/?”,”route”:”pages/video/search/VideoSearchPage”},{“key”:”/video/recommendations/?”,”route”:”pages/video/recommendations/VideoRecommendationsPage”},{“key”:”/video/top/?”,”route”:”pages/video/top/VideoTopPage”},{“key”:”/video/top/page/:num/?”,”route”:”pages/video/top/VideoTopPage”},{“key”:”/video/slice/:shortUrl/?”,”route”:”pages/video/slice/VideoSlicePage”},{“key”:”/video/slice/:shortUrl/:page/?”,”route”:”pages/video/slice/VideoSlicePage”},{“key”:”/video/embed/:id/?”,”route”:”pages/video/embed/by-id/VideoEmbedByIdPage”},{“key”:”/video/embed/:domain/:user/:id/?”,”route”:”pages/video/embed/by-external-id/VideoEmbedByExternalIdPage”},{“key”:”/music/?”,”route”:”pages/music/main/MusicMainPage”},{“key”:”/music/recommendations/?”,”route”:”pages/music/recommendations/MusicRecommendationsPage”},{“key”:”/music/songs/:fileId/?”,”route”:”pages/music/songs/main/MusicSongsMainPage”},{“key”:”/music/songs/:fileId/related/?”,”route”:”pages/music/songs/related/MusicSongsRelatedPage”},{“key”:”/music/songs/:fileId/fans/?”,”route”:”pages/music/songs/fans/MusicSongsFansPage”},{“key”:”/music/genre/:genre/?”,”route”:”pages/music/genre/main/MusicGenreMainPage”},{“key”:”/music/genre/:genre/tracks/?”,”route”:”pages/music/genre/tracks/MusicGenreTracksPage”},{“key”:”/music/genre/:genre/artists/?”,”route”:”pages/music/genre/artists/MusicGenreArtistsPage”},{“key”:”/music/genre/:genre/albums/?”,”route”:”pages/music/genre/albums/MusicGenreAlbumsPage”},{“key”:”/music/genre/:genre/playlists/?”,”route”:”pages/music/genre/playlists/MusicGenrePlaylistsPage”},{“key”:”/music/genre/:genre/fans/?”,”route”:”pages/music/genre/fans/MusicGenreFansPage”},{“key”:”/music/moderation/?”,”route”:”pages/music/moderation/main/MusicModerationMainPage”},{“key”:”/music/moderation/awaiting/?”,”route”:”pages/music/moderation/awaiting/MusicModerationAwaitingPage”},{“key”:”/music/moderation/artists/?”,”route”:”pages/music/moderation/artists/MusicModerationArtistsPage”},{“key”:”/music/moderation/artists/:artist/?”,”route”:”pages/music/moderation/artists/MusicModerationArtistsPage”},{“key”:”/moderation/wisher/holidays/?”,”route”:”pages/moderation/wisher/holidays/ModerationWisherHolidaysPage”},{“key”:”/moderation/wisher/calendars/?”,”route”:”pages/moderation/wisher/calendars/ModerationWisherCalendarsPage”},{“key”:”/moderation/wisher/gifts/?”,”route”:”pages/moderation/wisher/gifts/ModerationWisherGiftsPage”},{“key”:”/moderation/wisher/promo-video/?”,”route”:”pages/moderation/wisher/promo-video/ModerationWisherPromoVideoPage”},{“key”:”/moderation/wisher/masks/?”,”route”:”pages/moderation/wisher/masks/ModerationWisherMaskPage”},{“key”:”/mimic/redirect/?”,”route”:”pages/mimic/MimicRedirectPage”}],”pageName”:”ssi/top-menu”,”userAgent”:”Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.5304.88 Safari/537.36″,”isTestServer”:false,”isLocalServer”:false,”isBeta”:false,”isPsi”:false,”isUseJsMin”:true,”isUseJsHash”:true,”isShareHeaders”:false,”meta”:{“title”:null,”description”:null,”keywords”:null,”canonicalLink”:null,”alternateLink”:null,”noIndex”:false},”share”:{“title”:null,”description”:null,”type”:null,”url”:null,”siteName”:null,”images”:null,”image”:null},”options”:{“upload”:{“photo”:{“uploadUrl”:”https://upload-##n##.my.mail.ru/uploadphoto”,”hostCount”:”15″,”queueSize”:”15″,”previewQueueSize”:”1″,”limit”:”5000″,”rotateTimeout”:”1500″,”maxRetry”:”5″,”albumId”:null,”locales”:{“popup”:{“header”:”Добавление фото”,”close”:”Закрыть”,”confirmCloseYes”:”Да”,”confirmCloseNo”:”Нет”,”confirmCloseText”:”Хотите прекратить загрузку
и удалить все загруженные фото?”},”dropArea”:{“header”:”Выберите фото для загрузки”,”text”:”или просто перетащите их в эту область”,”button”:”С компьютера”,”moveHere”:”Перенесите файл(ы) в эту область”},”links”:{“albums”:”Из альбомов”,”network”:”По ссылке из интернета”,”camera”:”C веб-камеры”,”add”:”Добавить”},”status”:{“from”:”из”},”limit”:{“header”:” “,”content”:”К сожалению, мы можем загрузить не более 5000 фото за один раз. Добавить первые 5000 фото из выбранных?”,”close”:”Закрыть”,”yes”:”Да, добавить”,”no”:”Нет”},”albums”:{“title”:”Альбом”,”defaultAlbumName”:”Без названия”,”upload”:”Добавить”,”cancel”:”Отмена”,”titles”:{“user”:”из своих”,”group”:”из группы”,”channel”:”из канала”},”form”:{“title”:”Альбом”,”empty”:”В альбоме нет фото”}},”network”:{“upload”:”Загрузить”,”cancel”:”Отмена”,”header”:”Введите ссылку из интернета”,”remove”:”Удалить”,”add”:”Добавить ещё ссылку”,”errors”:{“invalidExternalUrl”:”Указан некорректный адрес”}},”camera”:{“upload”:”Загрузить”,”cancel”:”Отмена”,”button”:”Сделать снимок”,”timeout”:”С задержкой в 5 сек”,”cancelPhoto”:”Отменить”},”edit”:{“save”:”Сохранить”,”cancel”:”Остановить загрузку”,”remove”:”Удалить”,”add”:”Добавить фото”,”saveNow”:”Сохраняю”,”showErrors”:”Ошибки”,”empty”:{“text”:”К сожалению, при загрузке фото возникли проблемы.”,”button”:”Вернуться”},”confirmStop”:{“yes”:”Да”,”no”:”Нет”,”text”:”Хотите прекратить загрузку?”},”confirmRemove”:{“yes”:”Да”,”no”:”Нет”,”text”:”Хотите удалить все загруженные фото?”},”errors”:{“header”:”Не удалось загрузить файлы”,”network”:”указан некорректный адрес”,”upload_error”:”ошибка при загрузке”,”empty_file_size”:”пустой файл”,”wrong_file_size”:”слишком большой файл”,”too_many_files”:”слишком много фотографий”,”wrong_image_format”:”неподдерживаемый формат”,”wrong_gif_image”:”в альбом “Фото со мной” нельзя загружать анимированные картинки”},”item”:{“description”:”Описание”,”remove”:”Удалить”,”hide”:”Закрыть”}}}},”video”:{“userId”:””,”isEnableSelectFromAlbums”:true,”isEnableSelectToAlbum”:true,”isVideoChannel”:false,”maxFileSize”:”5″,”multiload”:true,”pollingTimeout”:”30″,”uploadUrl”:”//upload.my.myalpha4.i.mail.ru/upload”,”showSwitcher”:false,”albums”:{“singleSelect”:false},”albumId”:”_myvideo”,”locales”:{“errorLoadAjax”:”Произошла ошибка, попробуйте позже”,”popupButtonOk”:”Сохранить”,”popupButtonCancel”:”Удалить”,”popupButtonCancelAll”:”Остановить загрузку”,”closeButton”:”Закрыть”,”addVideo”:”Добавление видео”,”maxFileSize”:”Максимальный размер файла 5 Гб”,”timeRemain”:”осталось”,”wrongFormat”:”Неверный формат файла”,”wrongSize”:”Неверный размер файла”,”chooseOneFile”:”Выберите 1 файл для загрузки”,”connectionError”:”К сожалению, при загрузке видео возникли проблемы.”,”serverResponseError”:”Неизвестная ошибка.”,”createItemError”:”Ошибка создания видео.”,”blacklistedError”:”Загрузка данного видео заблокирована правообладателем.”,”invalidLink”:”Ссылка не может быть обработана”,”confirmYes”:”Да”,”confirmNo”:”Нет”,”confirmRemoveAll”:”Хотите прекратить загрузку и удалить все загруженные видео?”,”confirmCancelAll”:”Хотите прекратить загрузку?”,”linkLoadingTitle”:”Получение данных”,”defaultAlbumName”:”Без названия”,”albums”:{“albumErrorPopupHeader”:”При добавлении этих видео произошла ошибка”,”albumErrorPopupButtonOk”:”Закрыть”,”defaultAlbumName”:”Без названия”,”defaultItemName”:”Без названия”,”userAlbum”:”Мои альбомы”,”channelAlbum”:”Видео канала”,”communityAlbum”:”Видео группы”,”album”:”Альбом”,”private”:”Этот альбом не предназначен для публичного просмотра. Если вы скопируете видео в группу, для него будут применены настройки показа видео группы”,”empty”:”В выбранном альбоме нет видео”,”submit”:”Добавить”,”cancel”:”Отмена”,”privateAll”:”У вас нет роликов, предназначенных для публичного просмотра. Вы можете изменить права доступа в настройках своих альбомов.”},”item”:{“createItemError”:”Ошибка создания видео.”,”hide”:”Скрыть”,”more”:”Подробнее”,”defaultAlbumName”:”Без названия”,”confirmYes”:”Да”,”confirmNo”:”Нет”,”confirmText”:”Хотите прекратить загрузку?”},”main”:{“header”:”Выберите файлы для загрузки”,”text”:”Просто перетащите файлы в эту область”,”uploadButton”:”Выберите файлы”,”fromInternet”:”По ссылке из интернета”,”add”:”Добавить”,”fromAlbums”:”Из ваших альбомов”,”album”:”Альбом”,”share”:”Рассказать друзьям о видео после обработки”},”error”:{“return”:”Вернуться”},”edit”:{“cancel”:”Отмена”,”uploadSuccess”:”Видео было успешно загружено!”,”uploadSuccessText”:”Теперь оно должно быть обработано. Обычно это занимает от нескольких минут до часа. Видео будет доступно по ссылке:”,”name”:”Название”,”description”:”Описание”,”album”:”Альбом”,”adult”:”Для взрослых 18+”},”header”:”Добавление видео”}},”audio”:{“uploadUrl”:”https://upload-##n##.my.mail.ru/uploadaudio”,”hostCount”:”15″,”queueSize”:”15″,”limitSize”:”500″,”enableSearch”:true,”locales”:{“popup”:{“albumsTitle”:”Выберите плейлист”,”header”:”Добавление музыки”,”close”:”Закрыть”,”confirmCloseYes”:”Да”,”confirmCloseNo”:”Нет”,”confirmCloseText”:”Хотите прекратить загрузку
и удалить все загруженные файлы?”},”dropArea”:”Перетащите файлы в эту область”,”fromDisk”:”или загрузите с компьютера”,”button”:”Выберите файлы”,”maxSize”:”Максимальный размер 500 Мб”,”copyright”:”Я подтверждаю, что загружаемые файлы не нарушают авторские права”,”links”:{“albums”:”Из плейлистов”,”search”:”Из поиска музыки”,”add”:”Добавить”},”errors”:{“no_auth”:”для загрузки необходимо авторизоваться”,”magic_error”:”ошибка при загрузке”,”access_denied”:”недостаточно прав для загрузки”,”empty_file_size”:”файл пуст”,”wrong_file_size”:”файл слишком большой”,”too_many_files”:”загружено слишком много файлов”,”wrong_format”:”не поддерживаемый формат файла”,”ratelimit”:”превышен лимит по загрузке аудиофайлов”,”file_exists”:”загружаемый файл уже существует”,”upload_error”:”ошибка при загрузке”,”copyright_violation”:”запись нарушает авторские права”,”playlist_is_full”:”плейлист заполнен, выбери другой плейлист”},”edit”:{“save”:”Сохранить”,”remove”:”Удалить”,”confirmRemove”:{“yes”:”Да”,”no”:”Нет”,”text”:”Хотите удалить всю загруженную музыку?”},”item”:{“name”:”Название”,”author”:”Исполнитель”,”remove”:”Удалить”,”edit”:”Редактировать”}},”albums”:{“title”:”Плейлист”,”defaultAlbumName”:”плейлист”,”defaultGroupAlbumName”:”плейлист группы”,”upload”:”Добавить”,”defaultName”:”Без названия”,”titles”:{“user”:”из своих”,”group”:”из группы”,”search”:”Поиск”},”form”:{“title”:”Плейлист”,”empty”:”В плейлисте нет музыки”}},”status”:{“from”:”из”},”search”:{“upload”:”Добавить”,”search”:”Поиск”,”defaultName”:”Без названия”,”empty”:”По вашему запросу ничего не найдено”,”start”:”Здесь будут показаны аудиозаписи”}}}},”likes”:{“locales”:{“like”:”Нравится”}},”miniProfile”:{“bubbleWidth”:255,”bubbleZIndex”:200,”coverFemalePath”:”profile/profile_cover_bg_1.png”,”coverMalePath”:”profile/profile_cover_bg_2.png”,”locales”:{“age”:{“text1″:”год”,”text2″:”года”,”text5″:”лет”},”commonFriendsCount”:{“text1″:”общий друг”,”text2″:”общих друга”,”text5″:”общих друзей”},”friendship”:{“send”:”Подружиться”,”friend”:”Ваш друг”,”request”:”Предложение отправлено”,”error”:”Произошла ошибка”},”friendsText1″:”У вас”,”friendsText2″:”среди которых”,”messageButtonText”:”Написать”}},”verify”:{“tryDelay”:”500″,”tryCount”:”3″,”locales”:{“popupPhoneButtonSubmit”:”Получить код”,”popupPhoneButtonCancel”:”Отмена”,”popupCodeButtonSubmit”:”Готово”,”popupCodeButtonCancel”:”Отмена”,”popupNoReceiveButtonSubmit”:”Вернуться”,”popupNoReceiveButtonCancel”:”Отмена”,”popupSuccessButtonSubmit”:”Закрыть”,”unknownError”:”Неизвестная ошибка”,”ltN”:”менее {% minutes %} минут”,”ltHour”:”менее часа”,”gtHour”:”более часа”,”phone”:{“header”:”Добавление мобильного телефона”,”mainText”:”Укажите свой мобильный телефон”,”additionalText”:”Укажите свой мобильный телефон, на него Вы получите бесплатное SMS-сообщение с кодом подтверждения.”,”country”:”Страна”,”yourPhone”:”Ваш телефон”},”code”:{“header”:”Подтверждение учетной записи”,”mainText”:”Введите код SMS-сообщения”,”additionalText”:”На номер было выслано SMS-сообщение с кодом подтверждения учетной записи.”,”retypePhone”:”Ввести другой телефон”,”inputCode”:”Введите код”},”success”:{“header”:”Подтверждение учетной записи”,”mainText”:”Учетная запись успешно подтверждена”,”additionalText”:”Указанный телефонный номер можно использовать для восстановления пароля и для получения SMS-уведомления”}}},”layers”:{“id”:null,”imageHost”:”content.foto.my.mail.ru”,”bannerCounter”:”10″,”hideBanner”:true,”video”:{“likeEnable”:false},”locales”:{“complaint”:{“progress”:”Жалоба отправляется”,”done”:”Жалоба принята”},”serverErrorMessage”:”‘Ой!
Кажется, что-то случилось!
Попробуйте обновить страницу через минуту.”,”videoAddTextTitle”:”Добавить в альбом”,”videoNotAvailable”:”Видео не доступно на вашем устройстве”,”videoMyAlbum”:”Мое видео”,”videoAddText”:”Добавить”,”quality”:”Качество:”,”notSupport”:”Браузер не поддерживает воспроизведение видео”,”copyLink”:”Копировать ссылку”,”copyFrameLink”:”Копировать ссылку с текущего кадра”,”copyEmbedCode”:”Копировать код для вставки”,”linkCopied”:”Ссылка скопирована”,”bubbleLinkHeader”:”Вы можете скопировать этот код на свою страницу.”,”linkToVideo”:”Ссылка на видео (URL)”,”useOldCode”:”Использовать старый код”,”unsupportMobileDevice”:”Не поддерживается на мобильных устройствах”,”like”:”Нравится”,”link”:”Ссылка”,”share”:”Поделиться”,”videoAddedToAlbum”:”Добавлено в альбом”,”defaultAlbumName”:”Без названия”,”videoFrom”:”Другие видео автора”,”videoFromCommunity”:”Другие видео группы”,”liteLoadingError”:”Ошибка загрузки данных”,”mediaErrAborted”:”Ошибка воспроизведения”,”mediaErrNetwork”:”Ошибка подключения к сети”,”mediaErrDecode”:”Видеофайл поврежден или не поддерживается кодеком”,”mediaErrSrcNotSupported”:”Данный видеоформат не поддерживается вашим браузером”,”accessError”:”Приватный ролик”,”needFlash”:”Для воспроизведения этого видео установите Adobe Flash Player
Загрузить с сайта Adobe.”,”channels”:{“joined”:”Вы подписались”,”for_moderate”:”Заявка на рассмотрении”,”error”:”Произошла ошибка”,”videoFrom”:”Другие видео канала”}}},”videoLayer”:{“isEnableUnsafeSearch”:false,”swfUrl”:”//my1.imgsmail.ru/r/video2/uvpv3.swf”,”locales”:{“close”:”Закрыть”,”related”:”Похожие”,”otherVideoAuthor”:”Другие видео автора”,”noResult”:”Нет видео”,”searchPlaceholder”:”Искать среди видео…”,”cancelSearch”:”Отменить поиск”,”searchButton”:”Найти”,”emptySearch”:”По вашему запросу не найдено ни одного видео”,”defaultName”:”Без названия”,”authText”:”Войдите или зарегистрируйтесь в Моем Мире, чтобы комментировать, делиться с друзьями и добавлять видео к себе”,”authLogin”:”Войти”,”authRegister”:”Зарегистрироваться”,”nextVideo”:”Следующее видео”,”autoplay”:”Автоматически”,”views”:{“one”:”просмотр”,”two”:”просмотра”,”five”:”просмотров”},”search”:{“hd”:”Высокое качество”,”unsafe”:”Безопасный поиск”,”duration”:{“long”:”Длинные”,”medium”:”Средние”,”short”:”Короткие”,”any”:”Любой длины”},”sort”:{“createdAt”:”По дате добавления”,”popular”:”По популярности”,”duration”:”По длительности”,”relevance”:”По релевантности”}}}},”photoLayer”:{“locales”:{“loading”:”Загружаю…”,”inputFriendName”:”Введите имя друга”,”chooseFriend”:”Или выберите друга из списка”,”choose”:”Выбрать”,”cancel”:”Отмена”,”errorCreateSelection”:”Не удалось создать отметку”,”selectionAlreadyExists”:”Уже есть на фото”,”itIsMe”:”Это я”,”uploaded”:”загружено”,”album”:”Альбом”,”editDescription”:”Редактировать описание”,”markFriends”:”Отметить друзей”,”rating”:”Рейтинг”,”allVotes”:”Все оценки”}},”audioPlayer”:{“locales”:{“audio_added”:”Трек добавлен”,”audio_deleted”:”Аудиозапись удалена”,”too_many_audio”:”Ошибка!
Вы можете хранить не более 1000 аудиофайлов”,”cannot_add_audio”:”Ошибка! Вы не можете добавлять аудиозаписи в это группу.”,”audio_ratelimit”:”Ошибка!
Вы не можете добавить в группу более 10 аудиофайлов за час.”,”cannot_delete_audio”:”Вы не можете удалять аудиозаписи в этой группе”,”audio_error”:”Не удалось добавить аудиозапись”,”audio_rep”:”Уже есть в вашем Мире”,”upload”:”загружено: “,”more”:”Загрузить еще треки”},”isUseNativeAudioPlayer”:true},”comments”:{“limit”:{“text”:”500″,”attached”:”3″,”leftTextShowWarning”:50},”photo”:{“albumId”:”_comments”},”locales”:{“placeholder”:”Написать комментарий…”,”send”:”Отправить”,”attached”:”Прикрепить”,”photo”:”Фотографии”,”video”:”Видео”,”audio”:”Музыка”,”answer”:”Ответ для”,”errors”:{“defaultError”:”Произошла ошибка, попробуйте позже”,”user_blocked”:”Пользователь добавил вас в чёрный список”}}},”errors”:{“locales”:{“title404″:”К сожалению, эта страница недоступна”,”title403″:”У вас нет прав доступа к этой странице”,”title500″:”Уважаемый пользователь!”,”text404″:”Возможно, вы указали неправильный адрес страницы, а может быть страница
была удалена или перемещена”,”text500″:”В данный момент нами ведутся безотлагательные работы по усовершенствованию сервиса.
Пожалуйста, попробуйте повторить попытку входа через 15 минут.
Приносим извинения за доставленные неудобства.”,”mainPage”:”Главная страница”,”help”:”Помощь”}},”dateTime”:{“locales”:{“months”:{“0″:”январь”,”1″:”февраль”,”2″:”март”,”3″:”апрель”,”4″:”май”,”5″:”июнь”,”6″:”июль”,”7″:”август”,”8″:”сентябрь”,”9″:”октябрь”,”10″:”ноябрь”,”11″:”декабрь”},”left”:{“months”:{“0″:”января”,”1″:”февраля”,”2″:”марта”,”3″:”апреля”,”4″:”мая”,”5″:”июня”,”6″:”июля”,”7″:”августа”,”8″:”сентября”,”9″:”октября”,”10″:”ноября”,”11″:”декабря”},”seconds”:{“one”:”секунду”,”two”:”секунды”,”five”:”секунд”},”minutes”:{“one”:”минуту”,”two”:”минуты”,”five”:”минут”},”hours”:{“one”:”час”,”two”:”часа”,”five”:”часов”},”now”:”только что”,”in”:”в”,”ago”:”назад”,”today”:”сегодня”,”yesterday”:”вчера”}}},”messages”:{“locales”:{“dates”:{“today”:”сегодня, в “,”now”:”только что”,”30seconds”:”30 секунд назад”,”15seconds”:”15 секунд назад”,”1minutes”:”1 минуту назад”,”2minutes”:”2 минуты назад”,”3minutes”:”3 минуты назад”,”4minutes”:”4 минуты назад”,”5minutes”:”5 минут назад”},”writeFriends”:”Написать друзьям”,”friendsListHeader”:”Выберите друга, чтобы начать общение”,”search”:”Поиск”,”goToUserPage”:”Перейти в Мир пользователя”,”sendGift”:”Сделать подарок”,”sendVipStatus”:”Подарить VIP статус”,”addToBlacklist”:”Добавить в черный список”,”deleteThread”:”Удалить всю переписку”,”addFriend”:”В друзья”,”friendshipInProgress”:”Предложение дружбы отправлено”,”friendshipOk”:”Подружились”,”deleteThreadConfirm”:”Вы действительно хотите удалить всю переписку?”,”deleteThreadYes”:”Удалить”,”deleteThreadNo”:”Отмена”,”deleteMessageConfirm”:”Вы действительно хотите удалить это сообщение?”,”addToBlacklistConfirm”:”Вы действительно хотите добавить пользователя в черный список?”,”addToBlacklistYes”:”Добавить”,”addToBlacklistNo”:”Отмена”,”writerMessage”:”пишет вам”,”noMessages”:”Сообщения в диалоге отсутствуют”,”addContentMessage”:”Чтобы отправить фото или видео, нажмите соответствующую иконку под полем для ввода текста”,”newMessageButton”:”Начать диалог”,”senderFormError”:”При отправке сообщения произошла ошибка. Попробуйте обновить страницу и повторить отправку.”,”senderFormErrorSuspended”:”Вы не можете писать пользователю, так как его Мир заблокирован.”,”senderFormErrorRestricted”:”Вы не можете писать пользователю, так как он принимает сообщения только от друзей.”,”textareaPlaceholder”:”Напишите сообщение”,”submitButton”:”Отправить”,”formHintEnter1″:”Enter – отправить”,”formHintEnter2″:”+Enter – перенос строки”,”formHintCtrlEnter1″:”+Enter – отправить”,”formHintCtrlEnter2″:”Enter – перенос строки”,”attachPhoto”:”Фото”,”attachVideo”:”Видео”,”selectSmile”:”Выберите смайлик”,”errorTexts”:{“activeInBlacklist”:”Вы были добавлены в черный список”,”journalInBlacklist”:”Пользователь добавлен в черный список”,”journalInBlacklistButton”:”Убрать из черного списка”,”friendsOnly”:”Пользователь принимает сообщения только от друзей”,”friendsOrFrfrOnly”:”Пользователь принимает сообщения только от друзей
или друзей друзей”,”noFriends”:”У Вас пока нет друзей”,”noFriendsButton”:”Добавить друзей”,”emptyListHead”:”Диалог не выбран”,”emptyListBody”:”Откройте уже начатый диалог из меню слева
или нажмите на кнопку”,”emptyListButton”:”Написать друзьям”},”emptySearch”:{“head”:”Диалог не найден”,”button”:”Искать среди друзей”,”body”:”По запросу %%query%% переписка не найдена”},”emptyFriends”:{“head”:”Никого не найдено”,”body”:”По запросу %%query%% найти друзей не удалось”}}},”notifications”:{“locales”:{“global”:{“error”:{“head”:”Упс, что-то пошло не так…”,”body1″:”Мы знаем о проблеме и уже работаем.”,”body2″:”Попробуйте обновить страницу или зайти попозже.”}},”games”:{“removeAllText”:”Вы уверены, что хотите удалить все уведомления от приложений?”,”removeAllButtonYes”:”Удалить”,”removeAllButtonNo”:”Отменить”},”error”:{“head”:”Упс, что-то пошло не так…”,”body1″:”Мы знаем о проблеме и уже работаем.”,”body2″:”Попробуйте обновить страницу или зайти попозже.”}}},”jsErrorsLog”:{“isEnable”:false,”prefix”:”monitoring-my”,”logPrefix”:”mybig-errors”},”pageCache”:{“key”:””,”isEnabled”:true,”version”:”2″,”expire”:3600000,”defaultExpire”:3600000,”stores”:[“music”,”video”]},”sprites”:{“all”:{“url”:”/static/sprites/all.html”,”revision”:{“key”:”sprites.all.rev”,”value”:”8f0e8e333e0403163ebbea34e2fc901a”},”data”:{“key”:”sprites.all.data”}},”music”:{“url”:”/static/sprites/music.html”,”revision”:{“key”:”sprites.music.rev”,”value”:”4105024ca74c624967bb079bba824cc4″},”data”:{“key”:”sprites.music.data”}}},”sprite”:{“url”:”/static/sprites/all.html”,”revision”:{“key”:”sprites.all.rev”,”value”:”8f0e8e333e0403163ebbea34e2fc901a”},”data”:{“key”:”sprites.all.data”}},”localStatic”:{“isEnableSwitcher”:false,”isTurnOn”:false},”dwh”:{“isEnable”:false},”topMenu”:{“isGameClient”:false,”isHideNav”:false,”placeholder”:”Искать”,”balance”:{“balance”:0,”locales”:{“refill”:”Пополнить”,”100k”:”100к+”}},”position”:”fixed”,”sections”:{“selected”:{“text”:”Группы”,”id”:”groups”}},”buttons”:[{“id”:”notifications”,”iconHtml”:”
“,”title”:”уведомления”,”clns”:”d816421,d816436″},{“id”:”messages”,”iconHtml”:”
“,”title”:”сообщения”,”clns”:”d1186406″},{“id”:”discussions”,”iconHtml”:”
“,”title”:”обсуждения”,”clns”:”d816421,d816426″},{“id”:”games”,”iconHtml”:”
“,”title”:”игры”,”clns”:”d816421,d816438″}],”counters”:{},”locales”:{“navigateTo”:{“apps”:”Все игры”},”search”:{“placeholder”:”Искать”,”placeholderGameClient”:”Искать игры”,”sections”:{“games”:”Игры”,”peoples”:”Люди”,”photo”:”Фото”,”music”:”Музыка”,”video”:”Видео”,”hashtags”:”Хэштеги”,”groups”:”Группы”,”internet”:”В интернете”}},”balance”:{“refill”:”Пополнить”,”100k”:”100к+”},”buttons”:{“notifications”:”уведомления”,”messages”:”сообщения”,”discussions”:”обсуждения”,”actions”:”акции”,”games”:”игры”,”profile”:”профиль”},”links”:{“music”:”Музыка”,”video”:”Видео”,”games”:”Игры”,”groups”:”Группы”},”exit”:”Выйти”,”vip”:”VIP-пользователь”}},”promoLogo”:false,”promoLogoLink”:”https://my.mail.ru/community/mir/multipost/4e1c00002dbf0003.html”},”allJsUrl”:”//my4.imgsmail.ru/mail/ru/images/js/myjs/mm/out/min/bundles/all_revf4a1ea0219.js”,”magic”:{},”console”:{“enable”:false,”cssUrl”:”//my2.imgsmail.ru/mail/ru/css/new/web-console_rev4fba4a556e.css”,”jsUrl”:”//my4.imgsmail.ru/mail/ru/images/js/myjs/mm/out/min/libs/console.js”,”extensionsUrl”:”//my4.imgsmail.ru/mail/ru/images/js/myjs/mm/out/min/console-extensions_revff85fd8484.js”},”branch”:null,”requirejsStartModules”:”[]”,”isRequirejsAsync”:false,”isRequirejsDefer”:true,”isEnableBooster”:false,”scriptsPostloadReloadTimeout”:”500″,”faviconUrl”:”//my3.imgsmail.ru/mail/ru/images/my/compass/static/favicon/favicon.ico”,”videoSwfUrl”:”//undefined/mail/ru/images/video2/uvpv3.swf?60″,”iframeTransportDomain”:”mail.ru”,”comet”:{“proxy”:”//mycomet.my.mail.ru/proxy.html?5″,”channel”:”//mycomet.my.mail.ru/v3/get_comet”,”timeout”:”90000″,”sharedWorkerUrl”:”/static/shared-worker.html?1″},”counters”:{“proxy”:”//my.mail.ru/static/myrb2.html”}}
Как узнать код картинки?
Ученик
(192),
закрыт
16 лет назад
дядяВитя
Просветленный
(41096)
16 лет назад
пользуйся броузером FireFox
там есть стандартная такая комманда, когда мышкой укажешь картинку и тыцнешь ПРАВОЙ кнопкой на нее – выпадет меню и есть комманда “свойства” – там и код и размер и всё-всё-всё
или тыкаешь опять ПРАВОЙ кнопокй и выбираешь “показать изображение” и картинка откроется в броузере ОТДЕЛЬНО от остального содержания сайта
Валерий Никитин
Ученик
(239)
5 лет назад
data:image/png;base64,R0lGODlhpwE0APcAAC85RTA7RjE7RjI8SDM9SDU+SjY/TDhBTThCTjlDTjtETzpEUDxGUTxGUj5HUj1IVEBJVEFKVUJLVkRNV0VOWUdQWkhQW0hRW0pTXUxUXktVYE1WYE9XYU1YZFBYYlFZY1BaZVBbZlRcZVVdZ1Rfa1dfaFdfaVZgbFlhaltia1hibVlkb1xkbV5lbl9ncF9rdmFocWNqc2Frd2RrdGZtdWdudmFteGNueWhvd2xze210e210fG91fXB3fnB3f3J4gHN6gXB7hnR6gnZ8g3h+hXWBjHqAh3uBiHiEjn6Din6EjH+FjH2Ik4CGjYGHjYOIj4SJkIeNk4OPmomOlIWRm4uQlo2SmI6TmZGWm5OYnZWZn5aboJicoZmdopqeo5Sgq5Whq5ejrp2hpp6ip5qmsZuos6CkqaGkqaKmqqSorKapraerr6mssKqusayvs66xtK+ytrCztrG0uLO2uba4u7a5vLi6vbm8v7u9wL2/wr3Awr/BxMHDxsPFx8XHycfJy8nKzMrMzszNz83P0M/Q0tHS09LT1dTV1tbX2NjY2drb3Nvb3Nzd3t7e3+Dg4OHi4uLi4uTk5Obm5i85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RS85RSwAAAAApwE0AEcI/wABCBxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatzIsaPHjyBDxpF0YSAQST8IEpBkp+ARSUJ+SBrCEIYkLgnrSIIwUACkRARt4gxJtKjRo0iTKl36sM3MgQ4OOWKA8MAZSVUSyqS5UI2k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
Время на прочтение
9 мин
Количество просмотров 255K
[FF D8]
Вам когда-нибудь хотелось узнать как устроен jpg-файл? Сейчас разберемся! Прогревайте ваш любимый компилятор и hex-редактор, будем декодировать это:
Специально взял рисунок поменьше. Это знакомый, но сильно пережатый favicon Гугла:
Последующее описание упрощено, и приведенная информация не полная, но зато потом будет легко понять спецификацию.
Даже не зная, как происходит кодирование, мы уже можем кое-что извлечь из файла.
[FF D8] — маркер начала. Он всегда находится в начале всех jpg-файлов.
Следом идут байты [FF FE]. Это маркер, означающий начало секции с комментарием. Следующие 2 байта [00 04] — длина секции (включая эти 2 байта). Значит в следующих двух [3A 29] — сам комментарий. Это коды символов “:” и “)”, т.е. обычного смайлика. Вы можете увидеть его в первой строке правой части hex-редактора.
Немного теории
Очень кратко:
- Обычно изображение преобразуется из цветового пространства RGB в YCbCr.
- Часто каналы Cb и Cr прореживают, то есть блоку пикселей присваивается усредненное значение. Например, после прореживания в 2 раза по вертикали и горизонтали, пиксели будут иметь такое соответствие:
- Затем значения каналов разбиваются на блоки 8×8 (все видели эти квадратики на слишком сжатом изображении).
- Каждый блок подвергается дискретно-косинусному преобразованию (ДКП), являющемся разновидностью дискретного преобразования Фурье. Получим матрицу коэффициетов 8×8. Причем левый верхний коэффициент называется DC-коффициентом (он самый важный и является усредненным значением всех значений), а оставшиеся 63 — AC-коэффициентами.
- Получившиеся коэффициенты квантуются, т.е. каждый умножается на коэффициент матрицы квантования (каждый кодировщик обычно использует свою матрицу квантования).
- Затем они кодируются кодами Хаффмана.
Закодированные данные располагаются поочередно, небольшими частями:
Каждый блок Yij, Cbij, Crij — это матрица коэффициентов ДКП (так же 8×8), закодированная кодами Хаффмана. В файле они располагаются в таком порядке: Y00Y10Y01Y11Cb00Cr00Y20…
Чтение файла
Файл поделен на секторы, предваряемые маркерами. Маркеры имеют длину 2 байта, причем первый байт [FF]. Почти все секторы хранят свою длину в следующих 2 байта после маркера. Для удобства подсветим маркеры:
Маркер [FF DB]: DQT — таблица квантования
- [00 43] Длина: 0x43 = 67 байт
- [0_] Длина значений в таблице: 0 (0 — 1 байт, 1 — 2 байта)
- [_0] Идентификатор таблицы: 0
Оставшимися 64-мя байтами нужно заполнить таблицу 8×8.
[A0 6E 64 A0 F0 FF FF FF]
[78 78 8C BE FF FF FF FF]
[8C 82 A0 F0 FF FF FF FF]
[8C AA DC FF FF FF FF FF]
[B4 DC FF FF FF FF FF FF]
[F0 FF FF FF FF FF FF FF]
[FF FF FF FF FF FF FF FF]
[FF FF FF FF FF FF FF FF]
Приглядитесь, в каком порядке заполнены значения таблицы. Этот порядок называется zigzag order:
Маркер [FF C0]: SOF0 — Baseline DCT
Этот маркер называется SOF0, и означает, что изображение закодировано базовым методом. Он очень распространен. Но в интернете не менее популярен знакомый вам progressive-метод, когда сначала загружается изображение с низким разрешением, а потом и нормальная картинка. Это позволяет понять что там изображено, не дожидаясь полной загрузки. Спецификация определяет еще несколько, как мне кажется, не очень распространенных методов.
- [00 11] Длина: 17 байт.
- [08] Precision: 8 бит. В базовом методе всегда 8. Это разрядность значений каналов.
- [00 10] Высота рисунка: 0x10 = 16
- [00 10] Ширина рисунка: 0x10 = 16
- [03] Количество каналов: 3. Чаще всего это Y, Cb, Cr или R, G, B
1-й канал:
- [01] Идентификатор: 1
- [2_] Горизонтальное прореживание (H1): 2
- [_2] Вертикальное прореживание (V1): 2
- [00] Идентификатор таблицы квантования: 0
2-й канал:
- [02] Идентификатор: 2
- [1_] Горизонтальное прореживание (H2): 1
- [_1] Вертикальное прореживание (V2): 1
- [01] Идентификатор таблицы квантования: 1
3-й канал:
- [03] Идентификатор: 3
- [1_] Горизонтальное прореживание (H3): 1
- [_1] Вертикальное прореживание (V3): 1
- [01] Идентификатор таблицы квантования: 1
Находим Hmax=2 и Vmax=2. Канал i будет прорежен в Hmax/Hi раз по горизонтали и Vmax/Vi раз по вертикали.
Маркер [FF C4]: DHT (таблица Хаффмана)
Эта секция хранит коды и значения, полученные кодированием Хаффмана.
- [00 15] Длина: 21 байт
- [0_] Класс: 0 (0 — таблица DC коэффициентов, 1 — таблица AC коэффициентов).
- [_0] Идентификатор таблицы: 0
Следующие 16 значений:
Длина кода Хаффмана: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Количество кодов: [01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
Количество кодов означает количество кодов такой длины. Обратите внимание, что секция хранит только длины кодов, а не сами коды. Мы должны найти коды сами. Итак, у нас есть один код длины 1 и один — длины 2. Итого 2 кода, больше кодов в этой таблице нет.
С каждым кодом сопоставлено значение, в файле они перечислены следом. Значения однобайтовые, поэтому читаем 2 байта:
- [03] — значение 1-го кода
- [02] — значение 2-го кода
Далее в файле можно видеть еще 3 маркера [FF C4], я пропущу разбор соответствующих секций, он аналогичен вышеприведенному.
Построение дерева кодов Хаффмана
Мы должны построить бинарное дерево по таблице, которую мы получили в секции DHT. А уже по этому дереву мы узнаем каждый код. Значения добавляем в том порядке, в каком указаны в таблице. Алгоритм прост: в каком бы узле мы ни находились, всегда пытаемся добавить значение в левую ветвь. А если она занята, то в правую. А если и там нет места, то возвращаемся на уровень выше, и пробуем оттуда. Остановиться нужно на уровне равном длине кода. Левым ветвям соответствует значение 0, правым — 1.
Деревья для всех таблиц этого примера:
В кружках — значения кодов, под кружками — сами коды (поясню, что мы получили их, пройдя путь от вершины до каждого узла). Именно такими кодами закодировано само содержимое рисунка.
Маркер [FF DA]: SOS (Start of Scan)
Байт [DA] в маркере означает — «ДА! Наконец-то то мы перешли к финальной секции!». Однако секция символично называется SOS.
- [00 0C] Длина: 12 байт.
- [03] Количество каналов. У нас 3, по одному на Y, Cb, Cr.
1-й канал:
- [01] Идентификатор канала: 1 (Y)
- [0_] Идентификатор таблицы Хаффмана для DC коэффициентов: 0
- [_0] Идентификатор таблицы Хаффмана для AC коэффициентов: 0
2-й канал:
- [02] Идентификатор канала: 2 (Cb)
- [1_] Идентификатор таблицы Хаффмана для DC коэффициентов: 1
- [_1] Идентификатор таблицы Хаффмана для AC коэффициентов: 1
3-й канал:
- [03] Идентификатор канала: 3 (Cr)
- [1_] Идентификатор таблицы Хаффмана для DC коэффициентов: 1
- [_1] Идентификатор таблицы Хаффмана для AC коэффициентов: 1
[00], [3F], [00] — Start of spectral or predictor selection, End of spectral selection, Successive approximation bit position. Эти значения используются только для прогрессивного режима, что выходит за рамки статьи.
Отсюда и до конца (маркера [FF D9]) закодированные данные.
Закодированные данные
Последующие значения нужно рассматривать как битовый поток. Первых 33 бит будет достаточно, чтобы построить первую таблицу коэффициентов:
Нахождение DC-коэффициента
1) Читаем последовательность битов (если встретим 2 байта [FF 00], то это не маркер, а просто байт [FF]). После каждого бита сдвигаемся по дереву Хаффмана (с соответствующим идентификатором) по ветви 0 или 1, в зависимости от прочитанного бита. Останавливаемся, если оказались в конечном узле.
2) Берем значение узла. Если оно равно 0, то коэффициент равен 0, записываем в таблицу и переходим к чтению других коэффициентов. В нашем случае — 02. Это значение — длина коэффициента в битах. Т. е. читаем следующие 2 бита, это и будет коэффициент:
3) Если первая цифра значения в двоичном представлении — 1, то оставляем как есть: DC = <значение>
. Иначе преобразуем: DC = <значение>-2^<длина значения>+1
. Записываем коэффициент в таблицу в начало зигзага — левый верхний угол.
Нахождение AC-коэффициентов
1) Аналогичен п. 1, нахождения DC коэффициента. Продолжаем читать последовательность:
2) Берем значение узла. Если оно равно 0, это означает, что оставшиеся значения матрицы нужно заполнить нулями. Дальше закодирована уже следующая матрица. В нашем случае значение узла: 0x31.
- Первый полубайт: 0x3 — именно столько нулей мы должны добавить в матрицу. Это 3 нулевых коэффициента.
- Второй полубайт: 0x1 — длина коэффициента в битах. Читаем следующий бит.
- Аналогичен п. 3 нахождения DC-коэффициента.
Читать AC-коэффициенты нужно пока не наткнемся на нулевое значение кода, либо пока не заполнится матрица.
В нашем случае мы получим:
и матрицу:
[2 0 3 0 0 0 0 0]
[0 1 2 0 0 0 0 0]
[0 -1 -1 0 0 0 0 0]
[1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
Вы заметили, что значения заполнены в том же зигзагообразном порядке? Причина использования такого порядка простая — так как чем больше значения v и u, тем меньшей значимостью обладает коэффициент Svu в дискретно-косинусном преобразовании. Поэтому, при высоких степенях сжатия малозначащие коэффициенты обнуляют, тем самым уменьшая размер файла.
Аналогично получаем еще 3 матрицы Y-канала…
[-4 1 1 1 0 0 0 0] [ 5 -1 1 0 0 0 0 0] [-4 2 2 1 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0] [-1 0 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0] [-1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
Но! Закодированные DC-коэффициенты — это не сами DC-коэффициенты, а их разности между коэффициентами предыдущей таблицы (того же канала)! Нужно поправить матрицы:
- DC для 2-ой: 2 + (-4) = -2
- DC для 3-ой: -2 + 5 = 3
- DC для 4-ой: 3 + (-4) = -1
[-2 1 1 1 0 0 0 0] [ 3 -1 1 0 0 0 0 0] [-1 2 2 1 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0] [-1 0 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0] [-1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
Теперь порядок. Это правило действует до конца файла.
… и по матрице для Cb и Cr:
[-1 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[ 1 1 0 0 0 0 0 0] [1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
Вычисления
Квантование
Вы помните, что матрица проходит этап квантования? Элементы матрицы нужно почленно перемножить с элементами матрицы квантования. Осталось выбрать нужную. Сначала мы просканировали первый канал. Он использует матрицу квантования 0 (у нас она первая из двух). Итак, после перемножения получаем 4 матрицы Y-канала:
[320 0 300 0 0 0 0 0] [-320 110 100 160 0 0 0 0]
[ 0 120 280 0 0 0 0 0] [ 0 0 140 0 0 0 0 0]
[ 0 -130 -160 0 0 0 0 0] [ 0 -130 0 0 0 0 0 0]
[140 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 480 -110 100 0 0 0 0 0] [-160 220 200 160 0 0 0 0]
[-120 -240 -140 0 0 0 0 0] [-120 0 -140 0 0 0 0 0]
[ 0 -130 0 0 0 0 0 0] [-140 -130 0 0 0 0 0 0]
[-140 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
… и по матрице для Cb и Cr.
[-170 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 180 210 0 0 0 0 0 0] [180 -210 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [240 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
Обратное дискретно-косинусное преобразование
Формула не должна доставить сложностей. Svu — наша полученная матрица коэффициентов. u — столбец, v — строка. Cx = 1/√2 для x = 0, а в остальных случаях = 1. syx — непосредственно значения каналов.
Приведу результат вычисления только первой матрицы канала Y (после обязательного округления):
[138 92 27 -17 -17 28 93 139]
[136 82 5 -51 -55 -8 61 111]
[143 80 -9 -77 -89 -41 32 86]
[157 95 6 -62 -76 -33 36 86]
[147 103 37 -12 -21 11 62 100]
[ 87 72 50 36 37 55 79 95]
[-10 5 31 56 71 73 68 62]
[-87 -50 6 56 79 72 48 29]
и для Cb Cr:
[ 60 52 38 20 0 -18 -32 -40] [ 19 27 41 60 80 99 113 120]
[ 48 41 29 13 -3 -19 -31 -37] [ 0 6 18 34 51 66 78 85]
[ 25 20 12 2 -9 -19 -27 -32] [-27 -22 -14 -4 7 17 25 30]
[ -4 -6 -9 -13 -17 -20 -23 -25] [-43 -41 -38 -34 -30 -27 -24 -22]
[ -37 -35 -33 -29 -25 -21 -18 -17] [-35 -36 -39 -43 -47 -51 -53 -55]
[ -67 -63 -55 -44 -33 -22 -14 -10] [ -5 -9 -17 -28 -39 -50 -58 -62]
[ -90 -84 -71 -56 -39 -23 -11 -4] [ 32 26 14 -1 -18 -34 -46 -53]
[-102 -95 -81 -62 -42 -23 -9 -1] [ 58 50 36 18 -2 -20 -34 -42]
Ко всем полученным значениям нужно прибавить по 128, а затем ограничить их диапазон от 0 до 255:
Y = min(max(0, Y + 128), 255)
Cb = min(max(0, Cb + 128), 255)
Cr = min(max(0, Cr + 128), 255)
Например: 138 → 266 → 255, 92 → 220 → 220 и т. д.
YCbCr в RGB
4 матрицы Y, и по одной Cb и Cr, так как мы прореживали каналы и 4 пикселям Y соответствует по одному Cb и Cr. Поэтому вычислять так: YCbCrToRGB(Y[y,x], Cb[y/2, x/2], Cr[y/2, x/2]):
function YCbCrToRGB(Y, Cb, Cr)
{
R = round(Y + 1.402 * (Cr-128))
G = round(Y - 0.34414 * (Cb-128) - 0.71414 * (Cr-128))
B = round(Y + 1.772 * (Cb-128) )
R = min(max(0, R), 255)
G = min(max(0, G), 255)
B = min(max(0, B), 255)
return R, G, B
}
// Псевдокод для нашего рисунка
for (y = 0; y < 16; ++y)
for (x = 0; x < 16; ++x)
R, G, B = YCbCrToRGB(Y[y,x], Cb[y/2, x/2], Cr[y/2, x/2])
Вот полученные таблицы для каналов R, G, B для левого верхнего квадрата 8×8 нашего примера:
R:
255 249 195 149 169 215 255 255
255 238 172 116 131 179 255 255
255 209 127 58 64 112 209 255
255 224 143 73 76 120 212 255
217 193 134 84 86 118 185 223
177 162 147 132 145 162 201 218
57 74 101 125 144 146 147 142
0 18 76 125 153 146 128 108
G:
220 186 118 72 67 113 172 205
220 175 95 39 29 77 139 190
238 192 100 31 16 64 132 185
238 207 116 46 28 72 135 186
255 242 175 125 113 145 193 231
226 211 188 173 172 189 209 226
149 166 192 216 230 232 225 220
73 110 167 216 239 232 206 186
B:
255 255 250 204 179 225 255 255
255 255 227 171 141 189 224 255
255 255 193 124 90 138 186 239
255 255 209 139 102 146 189 240
255 255 203 153 130 162 195 233
255 244 216 201 189 206 211 228
108 125 148 172 183 185 173 168
32 69 123 172 192 185 154 134
Конец
Вообще я не специалист по JPEG, поэтому вряд ли смогу ответить на все вопросы. Просто когда я писал свой декодер, мне часто приходилось сталкиваться с различными непонятными проблемами. И когда изображение выводилось некорректно, я не знал где допустил ошибку. Может неправильно проинтерпретировал биты, а может неправильно использовал ДКП. Очень не хватало пошагового примера, поэтому, надеюсь, эта статья поможет при написании декодера. Думаю, она покрывает описание базового метода, но все-равно нельзя обойтись только ей. Предлагаю вам ссылки, которые помогли мне:
- ru.wikipedia.org/JPEG — для поверхностного ознакомления
- en.wikipedia.org/JPEG — гораздо более толковая статья о процессах кодирования/декодирования
- JPEG Standard (JPEG ISO/IEC 10918-1 ITU-T Recommendation T.81) — не обойтись без 186-страничной спецификации
- impulseadventure.com/photo — Хорошие подробные статьи. По примерам я разобрался как строить деревья Хаффмана и использовать их при чтении соответствующей секции
- JPEGsnoop — На том же сайте есть отличная утилита, которая вытаскивает всю информацию jpeg-файла
[FF D9]