写真から住所

Exifデータから住所を取得

今、動いているソースをそのまま表示。

写真から住所を取得するサンプルコード

画像のEXIFデータから住所を取得するサンプル。(内包機能:複数ファイルアップロード、URLから複数の画像ファイル取得、画像のBASE64エンコーディング、GooogleMapV3連携・複数マーキング)


事前準備


サンプルコード

Controller

<?php
/**
 * Part of the kurobuta.jp.
 *
 * Copyright (c) 2015 kurobuta.jp Development Team
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * @version    1.0
 * @author     kurobuta.jp Development Team
 * @link       https://kurobuta.jp
 */

namespace Sample;

// Logger
use \Monolog\Logger;
use \
Monolog\Handler\ChromePHPHandler;

// Model
use \Sample\Model\Exif;
use \
Sample\Model\Address;
use \
Sample\Model\Html;

/**
 * Class Exifコントローラー
 */
class Controller_Exif extends \Controller
{
    
// サービスの説明
    
const SERVICE_TITLE '写真から住所';
    const 
SERVICE_SUB_TITLE 'Exifデータから住所を取得';
    const 
SERVICE_DESCRIPTION 'アップロード(複数)した写真、もしくはURLから住所を表示。';
    const 
SERVICE_KEYWORD 'php,fuelphp,photo,address,exif';

    
// 動作設定
    
const EARTH_RADIUS 6378.137// 地球の半径(km)
    
const MAX_FILES 10// 最大ファイル数
    
const LOCATION_NOW 'いまココ';

    
// Google map zoom level (km)
    
private static $_google_map_zoom_level = array(
        
'18' => 0.05'17' => 0.1'16' => 0.2'15' => 0.5'14' => 1'13' => 2'12' => 4'11' => 5'10' => 10,
        
'9' => 20'8' => 50'7' => 100'6' => 200'5' => 500'4' => 1000'3' => 2000'2' => 4000'1' => 5000'0' => 10000);

    
// Logger
    
private $_log null;
    
// Model
    
private $_exif null;
    private 
$_address null;
    private 
$_html null;

    
/**
     * 前処理
     *
     */
    
public function before()
    {
        
parent::before();
        
$this->_log = new Logger(__CLASS__);
        
$this->_log->pushHandler(new ChromePHPHandler());
    }

    
/**
     * インデックス処理振り分け
     *
     * @return \Fuel\Core\View
     */
    
public function action_index()
    {
        \
Log::info('[START]'.__METHOD__);
        
$results = array();
        
// Model生成
        
$this->_exif = new Exif();
        
$this->_address = new Address();
        
$this->_html = new Html();
        
// View生成 レイアウトビューを作成する
        
$view = \View::forge('layout');
        
// 画面の説明を設定
        
$view->set_global('title'self::SERVICE_TITLE);
        
$view->set_global('sub_title'self::SERVICE_SUB_TITLE);
        
$view->set_global('description'self::SERVICE_DESCRIPTIONfalse);
        
$view->set_global('keyword'self::SERVICE_KEYWORD);
        
//View生成 変数としてビューを割り当てる、遅延レンダリング
        
$view->head = \View::forge('head');
        
$view->application_head = \View::forge('exif/script_before');
        
$view->header = \View::forge('header');
        
$view->top = \View::forge('top');
        
$view->content = \View::forge('exif/content');
        
$view->footer = \View::forge('footer');
        
$view->application_footer = \View::forge('exif/script_after');
        
$type_name '';
        try {
            
// 要求別設定
            
switch (\Input::post('processing')) {
                case 
SERVICE_CLEAR_KEY:
                    
// クリア
                    
$type_name SERVICE_CLEAR_NAME;
                    break;
                case 
SERVICE_UPLOAD_KEY:
                    
// アップロード
                    
$type_name SERVICE_UPLOAD_NAME;
                    
$results $this->upload();
                    break;
                case 
SERVICE_URL_KEY:
                    
// URLから画像を取得
                    
$type_name SERVICE_URL_NAME;
                    
$str = !empty(\Input::post('input')) ? \Input::post('input') : '';
                    
$results $this->url_image($str);
                    break;
                default :
                    
$type_name SERVICE_ROOT_NAME;
                    break;
            }
        } catch (\
HttpServerErrorException $e) {
            
$error_message '住所の取得に失敗しました('.$type_name.')。';
            
$view->content->message $error_message;
            \
Log::error($error_message);
        } finally {
            
$view->application_footer->results $results;
            
$view->content->results $results;
            \
Log::info('[END]'.__METHOD__.', '.$type_name);
            return 
$view;
        }
    }

    
/**
     * アップロードファイルから住所変換を取得
     *
     * @return array
     */
    
private function upload()
    {
        
$results = array();
        
$files = array();

        \
Log::info('[START]'.__METHOD__);
        
// アップロード処理
        
if (\Upload::is_valid()) {
            \
Upload::save(); // ファイル格納
            
foreach (\Upload::get_files() as $node) {
                \
log::info('FILE:'.print_r($nodetrue));
                
array_push($files,
                    array(
                        
'pass_name' => $node['saved_to'],
                        
'file_name' => $node['saved_as'],
                    )
                );
            }
            
// 住所取得処理
            
$results $this->locations($files);
            
// アップロードファイルの削除
            
foreach ($files as $node) {
                
// ファイル削除
                
if (!unlink($node['pass_name'].$node['file_name'])) {
                    
$error_message 'ファイルの削除に失敗しました('.$node[pass_name].$node[file_name].')。';
                    \
Log::error($error_message);
                }
            }
        }
        \
Log::info('[END]'.__METHOD__);
        return 
$results;
    }

    
/**
     * URLから住所変換を取得
     *
     * @return array
     */
    
private function url_image($value)
    {
        \
Log::info('[START]'.__METHOD__);
        
// URLから画像のパスを取得
        
$this->_html->set_url($value);
        
$files $this->_html->get_images_file_pass();
        
// 住所取得処理
        
$results $this->locations($files);
        \
Log::info('[END]'.__METHOD__);
        return 
$results;
    }

    
/**
     * ロケーション情報
     *
     * @param array $files
     * @return array
     */
    
private function locations($files = array())
    {
        
$items = array();
        
$latitude_max 0;
        
$latitude_min PHP_INT_MAX;
        
$longitude_max 0;
        
$longitude_min PHP_INT_MAX;
        
$north_south_km 0;
        
$east_west_km 0;
        
$zoom_level 0;
        
$count 0;

        
// geo location On
        
$items $this->geo_location_On($items);
        
// ファイルから住所取得
        
foreach ($files as $node) {
            if (
self::MAX_FILES $count) {
                
// ファイルの拡張子チェック
                
$extensions str_getcsv(IMAGE_EXTENSIONS);
                
$info = new \SplFileInfo($node['file_name']);
                if (
in_array($info->getExtension(), $extensions)) {
                    
// 住所取得
                    
$this->_exif->set_pass_name($node['pass_name']);
                    
$this->_exif->set_file_name($node['file_name']);
                    \
Log::info('upload: '.$node['pass_name'].$node['file_name']);
                    
$this->_exif->read(); // Exifの読み込み
                    
\log::info('EXIF:'.mb_convert_encoding(print_r($this->_exif->get_exif(), true), 'UTF-8'));
                    
$address $this->_exif->get_address();
                    
// サムネイル生成
                    
$this->_exif->thumbnail_create();
                    
// 方角画像生成
                    
$this->_exif->direction_image_create();
                    
// 住所が存在するものを格納
                    
if (!empty($address)) {
                        
$latitude $this->_exif->get_latitude();
                        
$longitude $this->_exif->get_longitude();
                        
$this->_log->addInfo('北緯:'.$latitude);
                        
$this->_log->addInfo('東経:'.$longitude);
                        
$this->_log->addInfo('住所:'.$address);
                        
array_push($items,
                            array(
                                
'image_name' => $this->_exif->get_file_name(),
                                
'image' => $this->_exif->get_thumbnail(),
                                
'address' => $address,
                                
'latitude' => $latitude,
                                
'longitude' => $longitude,
                                
'direction' => $this->_exif->get_direction_image()
                            )
                        );
                        
$count++;
                    }
                }
            }
        }
        
// 北緯東経範囲計算
        
foreach ($items as $node) {
            if (
$node['latitude'] > $latitude_max$latitude_max $node['latitude'];
            if (
$node['latitude'] < $latitude_min$latitude_min $node['latitude'];
            if (
$node['longitude'] > $longitude_max$longitude_max $node['longitude'];
            if (
$node['longitude'] < $longitude_min$longitude_min $node['longitude'];
        }
        
$latitude_position = ($latitude_max $latitude_min) / 2// 北緯中心
        
$longitude_position = ($longitude_max $longitude_min) / 2// 東経中心
        
if (count($items) > 0) {
            
// 北緯の範囲(km)
            
$north_south_km deg2rad($latitude_max $latitude_min) * self::EARTH_RADIUS;
            
// 東経の範囲(km)
            
$east_west_km cos(deg2rad($latitude_max)) * self::EARTH_RADIUS deg2rad($longitude_max $longitude_min);
            
// Zoom level
            
$km_max max(array($north_south_km$east_west_km));
            foreach (
self::$_google_map_zoom_level as $key => $value) {
                
$value $value 2;
                if (
$value $km_max$zoom_level $key;
                else break;
            }
        }
        
// ログ出力
        
$this->_log->addInfo('北緯-最大:'.$latitude_max);
        
$this->_log->addInfo('北緯-最小:'.$latitude_min);
        
$this->_log->addInfo('北緯-最大:'.$longitude_max);
        
$this->_log->addInfo('北緯-最小:'.$longitude_min);
        
$this->_log->addInfo('北緯-ポジション:'.$latitude_position);
        
$this->_log->addInfo('東経-ポジション:'.$longitude_position);
        
$this->_log->addInfo('北緯の範囲(km):'.$north_south_km.'km');
        
$this->_log->addInfo('東経の範囲(km):'.$east_west_km.'km');
        
$this->_log->addInfo('Zoomレベル:'.$zoom_level.'('.self::$_google_map_zoom_level[$zoom_level].'km)');
        
// 結果
        
return array(
            
'items' => $items,
            
'latitude_position' => $latitude_position,
            
'longitude_position' => $longitude_position,
            
'zoom_level' => $zoom_level
        
);
    }

    
/**
     * GEO LOCATION から位置情報生成
     *
     * @param array $items
     * @return array
     * @throws \Exception
     */
    
private function geo_location_On($items = array())
    {
        
$latitude = !empty(\Input::post('latitude')) ? (double)\Input::post('latitude') : null;
        
$longitude = !empty(\Input::post('longitude')) ? (double)\Input::post('longitude') : null;
        if (isset(
$latitude) and isset($longitude)) {
            
$this->_log->addInfo('geo location latitude:'.$latitude);
            
$this->_log->addInfo('geo location longitude:'.$longitude);
            
$this->_address = new Address();
            
$this->_address->set_latitude($latitude);
            
$this->_address->set_longitude($longitude);
            
$this->_address->re_geocode();
            
$address $this->_address->get_address();
            
$this->_address->image_create(self::LOCATION_NOW);
            
array_push($items,
                array(
                    
'image_name' => self::LOCATION_NOW,
                    
'image' => $this->_address->get_image(),
                    
'address' => $address,
                    
'latitude' => $latitude,
                    
'longitude' => $longitude,
                )
            );
        }
        return 
$items;
    }

}

Model

photo

<?php
/**
 * Part of the kurobuta.jp.
 *
 * Copyright (c) 2015 kurobuta.jp Development Team
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * @version    1.0
 * @author     kurobuta.jp Development Team
 * @link       https://kurobuta.jp
 */

namespace Sample\Model;

/**
 * 画像モデル
 *
 * 画像に関わる処理を行う.
 */
class Photo extends \Model
{
    private 
$_pass_name ''// ファイルパス
    
private $_file_name ''// ファイル名
    
private $_thumbnail null// サムネイル

    /**
     * ファイルパス設定
     *
     * @param $value
     */
    
public function set_pass_name($value)
    {
        
$this->_pass_name $value;
    }

    
/**
     * ファイル名設定
     *
     * @param $value
     */
    
public function set_file_name($value)
    {
        
$this->_file_name $value;
    }

    
/**
     * ファイル名の取得
     *
     * @return string
     */
    
public function get_file_name()
    {
        return 
$this->_file_name;
    }

    
/**
     * パス・ファイル名の取得
     *
     * @return string
     */
    
public function get_file_name_full()
    {
        return 
$this->_pass_name.$this->_file_name;
    }

    
/**
     * サムネイルの設定
     *
     * @param $value
     */
    
public function set_thumbnail($value)
    {
        
$this->_thumbnail $value;
    }

    
/**
     * サムネイルの取得
     *
     * @return null
     */
    
public function get_thumbnail()
    {
        return 
$this->_thumbnail;
    }

}

exif

<?php
/**
 * Part of the kurobuta.jp.
 *
 * Copyright (c) 2015 kurobuta.jp Development Team
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * @version    1.0
 * @author     kurobuta.jp Development Team
 * @link       https://kurobuta.jp
 */

namespace Sample\Model;

// Logger
use \Monolog\Logger;
use \
Monolog\Handler\ChromePHPHandler;

/**
 * Exifモデル
 *
 * Exifに関わる処理を行う.
 */
class Exif extends Photo
{
    const 
THUMBNAIL_SIZE 100//サムネイルのサイズ
    
const ARROW_IMAGE 'images/arrow_02.png'// 方角イメージ

    // Model
    
private $_address null// 住所モデル

    
private $_exif = array(); // Exif Data
    
private $_latitude = array(); // 北緯
    
private $_longitude = array(); // 東経
    
private $_direction null// 方角
    
private $_direction_image null// 方角画像

    
function __construct()
    {
        
$this->_log = new Logger(__CLASS__);
        
$this->_log->pushHandler(new ChromePHPHandler());
    }

    
/**
     * EXIFの取得
     *
     * @return array
     */
    /**
     * @return mixed
     */
    
public function get_exif()
    {
        return 
$this->_exif;
    }

    
/**
     * 北緯の取得
     *
     * @return array
     */
    /**
     * @return mixed
     */
    
public function get_latitude()
    {
        return 
$this->_address->get_latitude();
    }

    
/**
     * 東経の取得
     *
     * @access  public
     * @return  string
     */
    /**
     * @return array
     */
    
public function get_longitude()
    {
        return 
$this->_address->get_longitude();
    }

    
/**
     * 住所の取得
     *
     * @return mixed
     */
    
public function get_address()
    {
        
// Model生成
        
$this->_address = new Address();
        
$this->_address->set_gps_latitude($this->_latitude);
        
$this->_address->set_gps_longitude($this->_longitude);
        
$this->_address->re_geocode();
        return 
$this->_address->get_address();
    }

    
/**
     * 方角画像の設定
     *
     * @param $value
     */
    
public function set_direction_image($value)
    {
        
$this->_direction_image $value;
    }

    
/**
     * 方角画像の取得
     *
     * @return null
     */
    
public function get_direction_image()
    {
        return 
$this->_direction_image;
    }

    
/**
     * Exifの読み込み
     *
     */
    
public function read()
    {
        
$this->_exif = @exif_read_data(parent::get_file_name_full(), 0true);
        if (isset(
$this->_exif['GPS']['GPSLatitude']) && isset($this->_exif['GPS']['GPSLongitude'])) {
            
$this->_latitude $this->_exif['GPS']['GPSLatitude'];
            
$this->_longitude $this->_exif['GPS']['GPSLongitude'];
            isset(
$this->_exif['GPS']['GPSDestBearing']) ? $this->_direction = (int)$this->_exif['GPS']['GPSDestBearing'] : $this->_direction null;
        }
    }

    
/**
     * サムネイルの生成
     *
     */
    
public function thumbnail_create()
    {
        
// EXIFのサムネイルを確認
        
$image exif_thumbnail($this->get_file_name_full(), $width$height$type);
        if (!
$image) {
            
// Exifのサムネイルが存在しない場合は元ファイルを使用する
            
$image file_get_contents($this->get_file_name_full());
        }
        
// リサイズ
        
$src = \imagecreatefromstring($image);
        
// 縮小サイズを取得
        
$width imagesx($src);
        
$height imagesy($src);
        
// 縦横比計算
        
$aspect_ratio $height $width;
        
// リサイズ計算
        
if ($width <= self::THUMBNAIL_SIZE) {
            
$new_w $width;
            
$new_h $height;
        } else {
            if (
$width $height) {
                
$new_h self::THUMBNAIL_SIZE;
                
$new_w abs($new_h $aspect_ratio);
            } else {
                
$new_w self::THUMBNAIL_SIZE;
                
$new_h abs($new_w $aspect_ratio);
            }
        }
        
// 新しいサイズの空画像を生成
        
$new_img imagecreatetruecolor($new_w$new_h);
        if (
ImageCopyResampled($new_img$src0000$new_w$new_h$width$height)) {
            
// Base64にエンコード
            
$temp_file tempnam(sys_get_temp_dir(), 'temp_img');
            
imagepng($new_img$temp_file);
            
$handle fopen($temp_file"r");
            
$contents fread($handlefilesize($temp_file));
            
fclose($handle);
            
$encode_data base64_encode($contents);
            
$this->set_thumbnail('data:image/png;base64,'.$encode_data);
            
// ファイル削除
            
if (!unlink($temp_file)) {
                
$error_message 'ファイルの削除に失敗しました('.$temp_file.')。';
                
$this->_log->addError($error_message);
            }
        };
        
// メモリ解放
        
imagedestroy($new_img);
        
imagedestroy($src);
    }

    
/**
     * 方角画像の生成
     *
     */
    
public function direction_image_create()
    {
        if (isset(
$this->_direction)) {
            
// 方角あり
            
$image = new \Imagick();
            
$image->readImage(APPPATH.self::ARROW_IMAGE);
            
$this->_log->addInfo(__METHOD__.' direction_image_create readImage:'.APPPATH.self::ARROW_IMAGE);
            
$image->rotateImage('none'$this->_direction);
            
$encode_data base64_encode($image);
            
$this->set_direction_image('data:image/png;base64,'.$encode_data);
        }
    }

}

address

<?php
/**
 * Part of the kurobuta.jp.
 *
 * Copyright (c) 2015 kurobuta.jp Development Team
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * @version    1.0
 * @author     kurobuta.jp Development Team
 * @link       https://kurobuta.jp
 */

namespace Sample\Model;

/**
 * 住所モデル
 *
 * 住所に関わる処理を行う.
 */
class Address extends \Model
{
    const 
RE_GEOCODE_SERVICE_URL 'http://www.finds.jp/ws/rgeocode.php'// 逆ジオコーディングサービスURL
    
const RE_GEOCODE_SERVICE_PARAM_LAT 'lat'// 北緯パラメータ名
    
const RE_GEOCODE_SERVICE_PARAM_LON 'lon'// 東経パラメータ名
    
const FONT_PATH '/usr/share/fonts/truetype/ArmedBanana/ArmedBanana.ttf'// フォントのパス
    
const FONT_SIZE 18//フォントサイズ

    
private $_gps_latitude = array(); // GPS北緯
    
private $_gps_longitude = array(); // GPS東経
    
private $_latitude ''// 北緯(10進)
    
private $_longitude ''// 東経(10進)
    
private $_address ''// 住所
    
private $_prefecture ''// 都道府県
    
private $_municipality ''// 市区町村
    
private $_section ''// 町丁目・字等
    
private $_home_number ''// 番地等
    
private $_aza ''// 町丁目・字
    
private $_image null// 画像

    /**
     * 住所を返す
     *
     * @return string
     */
    
public function get_address()
    {
        return 
$this->_address;
    }

    
/**
     * 北緯を返す(10進)
     *
     * @return string
     */
    
public function get_latitude()
    {
        return 
$this->_latitude;
    }

    
/**
     * 東経を返す(10進)
     *
     * @return string
     */
    
public function get_longitude()
    {
        return 
$this->_longitude;
    }

    
/**
     * 北緯設定(10進数)
     *
     * @param $values
     */
    
public function set_latitude($values)
    {
        
$this->_latitude $values;
    }

    
/**
     * 東経設定(10進数)
     *
     * @param $values
     */
    
public function set_longitude($values)
    {
        
$this->_longitude $values;
    }

    
/**
     * 北緯設定(60進数)
     *
     * @param $values
     */
    
public function set_gps_latitude($values)
    {
        
$this->_gps_latitude $values;
        
$this->_latitude self::convert_decimal($values);
    }

    
/**
     * 東経設定(60進数)
     *
     * @param $values
     */
    
public function set_gps_longitude($values)
    {
        
$this->_gps_longitude $values;
        
$this->_longitude self::convert_decimal($values);
    }

    
/**
     * 画像の設定
     *
     * @param $value
     */
    
public function set_image($value)
    {
        
$this->_image $value;
    }

    
/**
     * 画像の取得
     *
     * @return null
     */
    
public function get_image()
    {
        return 
$this->_image;
    }

    
/**
     * 逆ジオコーディング
     *
     * @throws \Exception
     */
    
public function re_geocode()
    {
        
// 北緯東経が0位外実行
        
if ($this->_latitude == or $this->_longitude == 0) return;
        try {
            
// 外部サービスから住所を取得
            
$url self::RE_GEOCODE_SERVICE_URL.'?'.
                
self::RE_GEOCODE_SERVICE_PARAM_LAT.'='.$this->_latitude.'&'.
                
self::RE_GEOCODE_SERVICE_PARAM_LON.'='.$this->_longitude;
            
$data simplexml_load_file($url);
            
// ステータス確認
            
if ($data->status != '200') throw new \HttpServerErrorException;
            
// 取得住所の保存
            
$this->set_address($data->result);
        } catch (\
Exception $e) {
            throw 
$e;
        }
    }

    
/**
     * 配列から住所情報を設定
     *
     * @param $values
     */
    
private function set_address($values)
    {
        
$this->_prefecture = isset($values->prefecture->pname) ? (string)$values->prefecture->pname '';
        
$this->_municipality = isset($values->municipality->mname) ? (string)$values->municipality->mname '';
        
$this->_section = isset($values->local->section) ? (string)$values->local->section '';
        
$this->_home_number = isset($values->local->homenumber) ? (string)$values->local->homenumber '';
        
$this->_aza = isset($values->aza->name) ? (string)$values->aza->name '';
        
$this->_address $this->_prefecture.$this->_municipality.$this->_section.$this->_home_number.$this->_aza;
    }

    
/**
     * 緯度・経度の、60進数表記(度・分・秒表記)から10進数表記へ変換
     *
     * @param $values
     * @return float|int
     */
    
private static function convert_decimal($values)
    {
        
$decimal 0;
        if (isset(
$values[0]) and isset($values[1]) and isset($values[2])) {
            
// 度
            
$degrees explode("/"$values[0]);
            
$degrees = (double)$degrees[0] / (double)$degrees[1];
            
// 分
            
$minutes explode("/"$values[1]);
            
$minute = (double)$minutes[0] / (double)$minutes[1] / 60;
            
// 秒
            
$seconds explode("/"$values[2]);
            
$second = (double)$seconds[0] / (double)$seconds[1] / 3600;
            
// 
            
$decimal $degrees $minute $second;
        }
        return 
$decimal;
    }

    
/**
     * 画像の生成
     *
     * @param $value
     */
    
public function image_create($value)
    {
        if (isset(
$value)) {
            
$value $value."\n".$this->_address;
        } else {
            
$value $this->_address;
        }
        
$tx 2//最初の文字のX座標のベースポイント
        
$ty self::FONT_SIZE 1.15//フォントペースラインの位置
        
$box imagettfbbox(self::FONT_SIZE0self::FONT_PATH$value); // 大きさを測定
        
$width $box[2] - $box[6] + self::FONT_SIZE 0.35 4//幅の設定
        
$height $box[3] - $box[7] + 4// 高さの設定
        
$img imagecreatetruecolor($width$height);
        
$font_color imagecolorallocatealpha($img21000255);
        
$background_color imagecolorallocatealpha($img25525525545);
        
imagealphablending($imgtrue); // ブレンドモードを設定する
        
imagesavealpha($imgtrue); // 完全なアルファチャネルを保存する
        
imagefill($img00$background_color); // 指定座標から指定色で塗る
        
imagefttext($imgself::FONT_SIZE0$tx$ty$font_colorself::FONT_PATH$value); //テキスト描画
        
ob_start();
        
imagepng($img);
        
$string_data ob_get_contents();
        
ob_end_clean();
        
$encode_data base64_encode($string_data);
        
$this->set_image('data:image/png;base64,'.$encode_data);
        
imagedestroy($img);
    }

}

html

<?php
/**
 * Part of the kurobuta.jp.
 *
 * Copyright (c) 2015 kurobuta.jp Development Team
 * This software is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * @version    1.0
 * @author     kurobuta.jp Development Team
 * @link       https://kurobuta.jp
 */

namespace Sample\Model;

/**
 * HTMLモデル
 *
 * HTMLに関わる処理を行う.
 */
class Html extends \Model
{
    private 
$_url ''// url
    
private $_html ''// html

    /**
     * HTMLの設定
     *
     * @param $value
     */
    
public function set_html($value)
    {
        
$this->_html $value;
    }

    
/**
     * HTMLの取得
     *
     * @return string
     */
    
public function get_html()
    {
        return 
$this->_html;
    }

    
/**
     * URLの設定
     *
     * @param $value
     */
    
public function set_url($value)
    {
        
$this->_url $value;
    }

    
/**
     * URLの取得
     *
     * @return string
     */
    
public function get_url()
    {
        return 
$this->_html;
    }

    
/**
     * URLから画像のパスを取得
     *
     * @return array
     */
    
public function get_images_file_pass()
    {
        
$files = array();

        
// HTMLの取得
        
$this->_html file_get_contents($this->_url);
        
// 改行スペース除去
        
$html preg_replace('/\n|\r|\r\n|\t|\s/'''$this->_html);
        
// 画像タグ抽出
        
preg_match_all('/<img(.+?)>/'$html$img_tag_list);
        foreach (
$img_tag_list[1] as $node) {
            
// 画像パス抽出
            
$node preg_replace('/src=|\"|\'/'''$node);
            
// 定義された拡張子のみ処理の対象
            
$extensions str_getcsv(IMAGE_EXTENSIONS);
            foreach (
$extensions as $extension) {
                
preg_match_all('/(.+?)'.$extension.'/'$node$img_pass_splint);
                if (isset(
$img_pass_splint[0][0])) $img_pass $img_pass_splint[0][0];
            }
            if (isset(
$img_pass)) {
                
// パスにドメインがない場合はURLを保管
                
if (substr($img_pass01) == '/'$img_pass $this->_url.$img_pass;
                
// パスとファイル名分割
                
$path_parts pathinfo($img_pass);
                
// パスとファイルを保存
                
array_push($files,
                    array(
                        
'pass_name' => $path_parts['dirname'].'/',
                        
'file_name' => $path_parts['basename'],
                    )
                );
            }
        }
        return 
$files;
    }

}

View

<div class="container">
    <ul class="breadcrumb">
        <li><a href="/"><span class="glyphicon glyphicon-home"></span> ホーム</a></li>
        <li class="active"><span class="glyphicon glyphicon-list-alt"></span> サンプル</li>
        <li class="active"><span class="glyphicon glyphicon-cog"></span> <?php echo $title?></li>
        <li class="active"><a href="/sample/code/exif"><span
                    class="glyphicon glyphicon-pencil"></span> サンプルコード</a></li>
    </ul>
    <div class="row">
        <div class="col-md-4">
            <h2>入力</h2>
            <div>
                <label class="lead">位置情報</label>
                <div class="btn-group btn-toggle">
                    <button class="btn btn-lg btn-default">ON</button>
                    <button class="btn btn-lg btn-primary active">OFF</button>
                </div>
            </div>
            <!--タブ-->
            <ul class="nav nav-tabs">
                <li class="active"><a href="#upload" data-toggle="tab">アップロード(複数可)</a></li>
                <li><a href="#url" data-toggle="tab">ウェブページ(URL)</a></li>
            </ul>
            <div class="tab-content">
                <div class="tab-pane active" id="upload">
                    <?php echo Form::open(array('enctype' => 'multipart/form-data')); ?>
                    <?php echo Form::file(array('id' => 'form_upload_file''name' => 'upload_file[]''class' => 'file''multiple' => 'true''data-show-upload' => 'false''data-show-caption' => 'true''data-max-file-count' => 10)); ?>
                    <button type="submit" name="processing" value="<?php echo SERVICE_UPLOAD_KEY ?>"
                            class="add-on btn btn-primary btn-lg btn-block margin4px"><?php echo SERVICE_UPLOAD_NAME ?></button>
                    <div id="geo1"></div>
                    <?php echo Form::close(); ?>
                </div>
                <div class="tab-pane" id="url">
                    <?php echo Form::open(); ?>
                    <input type="url" id="input" name="input" placeholder="http://" value=""
                           class="form-control input-xx">
                    <button type="submit" name="processing" value="<?php echo SERVICE_URL_KEY ?>"
                            class="add-on btn btn-primary btn-lg btn-block margin4px"><?php echo SERVICE_URL_NAME ?></button>
                    <div id="geo2"></div>
                    <?php echo Form::close(); ?>
                </div>
            </div>
            <?php echo Form::open(); ?>
            <button type="submit" name="processing" value="<?php echo SERVICE_CLEAR_KEY ?>"
                    class="btn btn-default btn-xs btn-block btn-clear"><?php echo SERVICE_CLEAR_NAME ?></button>
            <?php echo Form::close(); ?>
            <ul>
                <li>1回のアップロード最大数は10枚です。</li>
                <li>アップロードされたファイルは保存されません。</li>
                <li>iPhone/iPadは、ファイルアップロード時にブラウザで位置情報が削除(仕様)されます。PCに保存し、PCからアップロードしてください。</li>
            </ul>
        </div>
        <div class="col-md-8">
            <h2>結果</h2>
            <?php
            
echo isset($message) ? '<p class="text-danger">'.$message.'</p>' '';
            echo empty(
$results['items']) ? '<p class="text-danger">位置情報のある写真はありません。</p>' '<p class="text-primary">位置情報の処理結果は'.count($results['items']).'件です。</p>';
            
?>
            <!--map-->
            <div id="map" style="width:100%; height:<?php echo empty($results['items']) ? '0px' '320px'?>"></div>
            <div class="table-responsive">
                <table class="table table-striped table-bordered table-hover table-condensed table-responsive">
                    <thead>
                    <tr class="success">
                        <th>
                            <small>画像</small>
                        </th>
                        <th>
                            <small>ファイル名</small>
                        </th>
                        <th>
                            <small>住所</small>
                        </th>
                        <th>
                            <small>方角</small>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    <?php
                    
if (!empty($results['items'])) {
                        foreach (
$results['items'] as $node) {
                            echo 
'<tr id="'.$node['image_name'].'">';
                            echo 
'<td><a href="#map_'.$node['image_name'].'"><img src="'.$node['image'].'"></a></td>';
                            echo 
'<td><a href="#map_'.$node['image_name'].'">'.$node['image_name'].'</a></td>';
                            echo 
'<td><a href="#map_'.$node['image_name'].'">'.$node['address'].'</a></td>';
                            echo 
'<td><a href="#map_'.$node['image_name'].'">';
                            echo isset(
$node['direction']) ? '<img src="'.$node['direction'].'"></a></td>' '';
                            echo 
'</a></td>';
                            echo 
'</tr>';
                        }
                    }
                    
?>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>