Здравствуйте!
Возникла задача для интернет-магазина сфотографировать большое количество товаров. Специфика товара такова, что не столько важна красивая картинка, сколько особенности конструкции товара (с какой стороны находится шлейф, есть ли петли крепления и т.п.)
Фотографировать обычным фотоаппаратом, потом заливать фото на компьютер, искать каждый товар в админке, потом искать соответствующее фото, показалось очень долго. Гораздо проще открыть товар в админке и навести телефон на товар. Тем более, что при хорошо выставленном освещении, современные смартфоны выдают вполне качественную картинку.
Теория
В андроид-маркете лежит замечательная программа IpWebCam, которая позволяет превратить свой телефон в полноценную веб-камеру. Кроме того у нее есть api для получения фотографий с автофокусом. При запуске IpWebCam, на телефоне поднимается web-сервер, который позволяет с локальной машины по wi-fi получать текущий кадр с телефона по адресу вида 192.168.0.14:8080/shot.jpg
Идея была следующая: Вставить в форму <img> с адресом фотографии со смартфона Создать canvas и в него скопировать содержимое <img> Сохранить данные при помощи canvas.toDataURL() Отправить данные на сервер при помощи ajax
К сожалению, из-за кросс-доменных политик метод toDataURL() сохраняет только черный квадрат вместо изображения. Поэтому canvas надо создавать на том же домене, из которого берется изображение. Сходив на сайт программы, я узнал, что IpWebCam позволяет создавать собственные html-страницы на своем внутреннем сервере. Для этого их достаточно залить на sd-карту и указать программе, в какой папке их искать.
Алгоритм следующий: На смартфоне создаем специальную страницу (например my.html) В форме на нашем сайте создаем <iframe>, в который грузим html-страницу со смартфона. На телефоне в html странице создаем canvas, в который грузим изображение с камеры. Сохраняем данные при помощи canvas.toDataURL() в переменную Передаем данные в родительскую страницу при помощи window.postMessage() В родительской странице получаем изображение и отправляем данные на сервер при помощи ajax На сервере сохраняем изображение в файл.
Решение
Во-первых, ставим на смартфон программу IpWebCam из маркета.
Создаем на смартфоне папку webcam, а в ней создаем файл my.html со следующим содержимым: Content-Type: text/html
<html> <head> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="jquery.jplayer.min.js"></script> <script type="text/javascript" src="common.js"></script> <style> * { margin: 0; padding: 0} </style> <script type="text/javascript"> $(loadJsWindowed); function shot() { $('#msg').text('Please wait...'); var img = new Image(); img.onload = function(){ var canvas = $('<canvas width="' + img.width + '" height="' + img.height + '">'); canvas[0].getContext('2d').drawImage(img, 0, 0); var data = canvas[0].toDataURL('image/jpeg').replace(/data:image\/jpeg;base64,/, ''); canvas.remove(); //засылаем картинку на сервер window.parent.postMessage(data, '*'); } img.src = 'photoaf.jpg'; } </script>
</head> <body> <div id="msg" style="text-align: center; background-color: #000000; color: #FFFFFF; font-weight: bold; cursor: pointer;" onclick="shot();">Click to take a shot..</div> <img id="img1" src="/shot.jpg?1" style="cursor: pointer; position:absolute;"/> <img id="img2" src="/shot.jpg?2" style="cursor: pointer; position:absolute;"/> </body> </html>
Обратите внимание, что в начале файла идут HTTP заголовки и пустая строка перед основным содержимым страницы. За основу был взят javascript видео-проигрыватель из самой программы.
Теперь надо указать, где искать файлы для веб-сервера приложения. Для этого откройте программу на телефоне, нажмите хардварную кнопку меню и выберите единственный пункт Cheats. Теперь введите в открывшемся диалоговом окне команду set(HtmlPath,/sdcard/webcam). Обратите внимание, что после запятой не допускаются пробелы.
Теперь на нашем сервере создаем файл jquery плагина jquery.ipwebcam.js: (function($) { $.fn.ipWebCam = function(options) { var settings = $.extend( { ip: '', width: 640, height: 480, action: '?', callback: function(){} }, options); function ipWebCam_listener(event){ $('#ipWebCam_wnd').prev().remove(); $('#ipWebCam_wnd').remove(); $.post(settings.action, {data:event.data}, settings.callback); }
if (window.addEventListener){ window.addEventListener('message', ipWebCam_listener,false); } else { window.attachEvent('onmessage', ipWebCam_listener); } return this.each(function() { $(this).click(function(){ if(settings.ip=='') settings.ip = prompt('IP Webcam address:'); $('<iframe>').css({ position: 'fixed', width: settings.width + 'px', marginLeft: '-' + (settings.width/2) + 'px', left: '50%', height: settings.height + 'px', marginTop: '-' + (settings.height/2) + 'px', top: '50%', border: 0, overflow: 'hidden', backgroundColor: '#777777' }) .attr('width', settings.width) .attr('height', settings.height) .attr('src', 'http://' + settings.ip + ':8080/my.html') .attr('id', 'ipWebCam_wnd') .prependTo('body');
$('<div>').css({ position:'fixed', left: 0, top: 0, right:0, bottom:0, backgroundColor: '#000000', opacity: 0.5 }).click(function(){ $('#ipWebCam_wnd').prev().remove(); $('#ipWebCam_wnd').remove(); }).prependTo('body'); }); }); }; })( jQuery )
Плагин цепляется к кнопке вызова диалога. Например: $('#camera_button').ipWebCam({ ip: '', //ip адрес камеры, если не задан, то попросит ввести через prompt action: 'save_img.php', //адрес скрипта сохранения картинки, по умолчанию та же страница callback: function(rep){ // будет вызвана после отправки данных на сервер window.location.reload(); }, width: 640, // размеры iframe height: 480 });
Плагин передает данные на сервер методом POST в переменной data. Сохранить файл на php: if(isset($_POST['data'])) { $name = 'img/shot.jpg'; //записываем, не забывая перекодировать из base64 file_put_contents($name, base64_decode($_POST['data'] )); echo 'ok'; }
На этом все, если кому-нибудь пригодится, буду рад.
upd Идея была в том, что администратор работает в админке за большим компом, так удобнее (он ведь не только фотки делает). А смартфон кладется на штатив и не трогается. Непосредственно фотографирование (предпросмотр и нажатие спуска) происходит на большом компе, чтобы лишний раз к телефону не бегать. Поэтому саму фотографию придется передавать непосредственно в html форму на большом компе. Это можно сделать только подняв веб-сервер на смарте. Можно было бы написать программу самому, но зачем если уже есть готовое решение — IpWebCam.
|