Автоматическое определение изображения для 360-градусной природы в PHP

Я отображаю страницу сведений об объекте недвижимости, как показано ниже (доступ к ней можно получить по адресу Здесь) введите здесь описание изображения

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

Я использую следующий контроллер для загрузки 360 изображений, который похож на загрузку обычных изображений.

public function upload_360_images()
{
    if($this->session->userdata['id'] && $this->session->userdata['type']=='user')
    {
        if($_FILES)
        {
            if(isset($_FILES['files'])){
                $data['errors']= array();
                $extensions = array("jpeg","jpg","png");

                foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){

                    $file_name = $key.$_FILES['files']['name'][$key];
                    $file_size =$_FILES['files']['size'][$key];
                    $file_tmp =$_FILES['files']['tmp_name'][$key];
                    $file_type=$_FILES['files']['type'][$key];
                    /*$file_ext=explode('.',$_FILES['image']['name'][$key]) ;
                    $file_ext=end($file_ext);*/
                    $i=1;
                    if($file_size > 7097152){
                        $data['errors'][$i]='File '.$i.' size must be less than 7 MB';
                        $i++;
                    }

                    $desired_dir="uploads";
                    if(empty($data['errors'])==true){
                        if(is_dir($desired_dir)==false){
                            mkdir("$desired_dir", 0700);        // Create directory if it does not exist
                        }
                        if(is_dir("$desired_dir/".$file_name)==false){
                            move_uploaded_file($file_tmp,"uploads/".$file_name);
                            $this->post_model->add360Image('property_360_images',$file_name,$this->uri->segment(3));
                        }else{                                  //rename the file if another one exist
                            $new_dir="uploads/".$file_name.time();
                            rename($file_tmp,$new_dir) ;
                        }

                    }else{
                        $data['contact']=$this->admin_model->getContactDetails();
                        $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
                        $data['title']='My Profile Image';
                        $this->load->view('site/static/head',$data);
                        $this->load->view('site/static/header');
                        $this->load->view('site/content/upload_360_images');
                        $this->load->view('site/static/footer');
                        $this->load->view('site/static/footer_links');
                    }
                }
                if(empty($data['errors']))
                {
                    redirect(base_url().'dashboard');
                }
                else
                {
                    $data['contact']=$this->admin_model->getContactDetails();
                    $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
                    $data['title']='My Profile Image';
                    $this->load->view('site/static/head',$data);
                    $this->load->view('site/static/header');
                    $this->load->view('site/content/upload_360_images');
                    $this->load->view('site/static/footer');
                    $this->load->view('site/static/footer_links');
                }
            }

        }
        else
        {
            $data['contact']=$this->admin_model->getContactDetails();
            $data['images']=$this->post_model->getProperty360Images($this->uri->segment(3));
            $data['title']='My Profile Image';
            $this->load->view('site/static/head',$data);
            $this->load->view('site/static/header');
            $this->load->view('site/content/upload_360_images');
            $this->load->view('site/static/footer');
            $this->load->view('site/static/footer_links');
        }

    }
    else
    {
        redirect(base_url().'user/login');
    }

}

Пожалуйста, не обращайте внимания на длинный код, этот код из производства, поэтому мне нужно поставить много проверок и условий.

Проблема Теперь мой работодатель хочет, чтобы я использовал единый интерфейс для загрузки как обычных изображений, так и изображений 360 и определял характер изображения с помощью некоторого алгоритма обнаружения, а затем отображал изображение в том же слайдере изображения, который я использую для статические/простые изображения.

Исследования

Я прочитал эту ветку в Stackoverflow, которая имеет небольшой смысл в чтении метаданных файла с использованием EXIF, но это делает этот процесс довольно ручным.

Вопрос

Я хочу автоматизировать чтение этого изображения, используя его в моем коде загрузки изображения php или написать этот алгоритм обнаружения в функции, которая получает имя изображения в качестве параметра и возвращает тип изображения как обычный или 360. На основе этого возврата я могу легко визуализировать представления. Итак, мой вопрос: как сделать это обнаружение в php?


person Malik Mudassar    schedule 27.02.2017    source источник
comment
взгляните на exiftool - он показывает метаинформацию поля зрения из тегов exif. Хотя нет гарантии его присутствия...   -  person Hokascha    schedule 13.04.2017
comment
Возможно, EXIF PHP Extension не было, когда был задан этот вопрос , но нет причин, по которым чтение или создание метаданных EXIF ​​должно быть ручным процессом.   -  person ashleedawg    schedule 08.09.2019


Ответы (2)


Согласно группе Facebook 360:

Пока еще не существует стандарта для пометки фотографий как содержащих 360-контент.

Это предлагает вам искать тег EXIF

Projection Type : equirectangular

Вы также можете искать

Use Panorama Viewer : True

Эти две метки присутствуют на фотографиях, сделанных на мой LG 360.

person Terence Eden    schedule 07.08.2017
comment
Действительные равнопрямоугольные изображения также будут иметь соотношение сторон 2:1. - person ashleedawg; 08.09.2019

Я столкнулся с аналогичной проблемой для платформы Unity3D, но я понял это, учитывая, что равнопрямоугольные изображения обычно имеют пропорции 2: 1.

Вероятная ширина 2000 пикселей и высота 1000 пикселей (я уже видел программное обеспечение, генерирующее высоту немного выше).

Вот псевдокод, имейте в виду, что этот код рассматривает posX и posY, начиная с нижнего левого угла:

//this is how much the image should be close the 2:1 proportion, or 0.5-proportionThreshold.
proportionThreshold = 0.01;

//images smaller than this should not have resolution enough to be a panorama.
//it is important here to 
minimumWidth = 2000;
minimumHeight = 1080;

//in case of the image is not a panorama, this variable determines the maximum size it could be projected
maxFill = 0.65;

//what is the amount of the view the pamorama should view:
scaleX = 1;
scaleY = 1;

//where the panorama should be positioned in the view:
posX = 0;
posY = 0;

currentWidth = source.width;
currentHeight = source.height;

if(isFullPanorama()){
    Log("Full Panorama");
    //the variables are already set for that
}else if(isPartialPanorama()){
    Log("Partial Panorama");
    scale = currentHeight/currentWidth * 2f;
    scaleX = 1;
    scaleY = scale;
    posX = 0;
    posY = 0.5-scale/2;
}else{
    Debug.Log("Not Panorama");
    proportion = currentHeight/currentWidth;
    w = currentWidth > minimumWidth*maxFill ? minimumWidth*maxFill : currentWidth;
    scaleX = w / minimumWidth / 2;
    scaleY = scaleX * proportion * 2;
    if(scaleY>1) {
        h = currentHeight > minimumHeight*maxFill ? minimumHeight*maxFill : currentHeight;
        scaleY = h / minimumHeight / 2;
        scaleX = scaleY * proportion / 2;
    }
    posX = 0.5-scaleX/2;
    posY = 0.5-scaleY/2;
}

bool isFullPanorama(){
    proportion = currentHeight/currentWidth;
    return proportion>=0.5-proportionThreshold &&
    proportion<=0.5+proportionThreshold &&
    source.height >= minimumHeight;
}

bool isPartialPanorama(){
    return currentHeight/currentWidth<=0.5 &&
    source.width >= minimumWidth;
}
person Carlos Oliveira    schedule 14.09.2017