1

を使用して画像から取得した配列があります

exif_read_data($image, 0, true)

配列自体には、不明な数のキー/値が含まれる場合があります (0 の場合もあります)。また、配列の一部は多次元です。

exif_read_data からの配列の例:

Array
(
    [FILE] => Array
        (
            [FileName] => f-20110129_004_pp.jpg
            [FileDateTime] => 0
            [FileSize] => 3566966
            [FileType] => 2
            [MimeType] => image/jpeg
            [SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS
        )

    [COMPUTED] => Array
        (
            [html] => width="2576" height="1936"
            [Height] => 1936
            [Width] => 2576
            [IsColor] => 1
            [ByteOrderMotorola] => 0
            [ApertureFNumber] => f/2.8
            [Thumbnail.FileType] => 2
            [Thumbnail.MimeType] => image/jpeg
        )

    [IFD0] => Array
        (
            [ImageWidth] => 2576
            [ImageLength] => 1936
            [BitsPerSample] => Array
                (
                    [0] => 8
                    [1] => 8
                    [2] => 8
                )

            [Make] => Nokia
            [Model] => N900
            [Orientation] => 1
            [SamplesPerPixel] => 3
            [XResolution] => 3000000/10000
            [YResolution] => 3000000/10000
            [ResolutionUnit] => 2
            [Software] => Adobe Photoshop CS5 Windows
            [DateTime] => 2011:01:29 09:37:30
            [YCbCrPositioning] => 1
            [Exif_IFD_Pointer] => 276
            [GPS_IFD_Pointer] => 658
        )

    [THUMBNAIL] => Array
        (
            [Compression] => 6
            [XResolution] => 72/1
            [YResolution] => 72/1
            [ResolutionUnit] => 2
            [JPEGInterchangeFormat] => 978
            [JPEGInterchangeFormatLength] => 5525
        )

    [EXIF] => Array
        (
            [ExposureTime] => 1/500
            [FNumber] => 14/5
            [ExposureProgram] => 0
            [ISOSpeedRatings] => 100
            [ExifVersion] => 0210
            [DateTimeOriginal] => 2011:01:29 09:37:30
            [DateTimeDigitized] => 2011:01:29 09:37:30
            [ShutterSpeedValue] => 8/1
            [ApertureValue] => 297/100
            [LightSource] => 0
            [Flash] => 0
            [FocalLength] => 26/5
            [FlashPixVersion] => 0100
            [ColorSpace] => 1
            [ExifImageWidth] => 2576
            [ExifImageLength] => 1936
            [CustomRendered] => 0
            [ExposureMode] => 0
            [WhiteBalance] => 0
            [DigitalZoomRatio] => 1/1
            [SceneCaptureType] => 0
            [GainControl] => 0
            [Contrast] => 0
            [Saturation] => 0
        )

    [GPS] => Array
        (
            [GPSVersion] => 
            [GPSLatitudeRef] => N
            [GPSLatitude] => Array
                (
                    [0] => 22/1
                    [1] => 12937/1000
                    [2] => 0/1
                )

            [GPSLongitudeRef] => E
            [GPSLongitude] => Array
                (
                    [0] => 113/1
                    [1] => 32886/1000
                    [2] => 0/1
                )

            [GPSAltitudeRef] => 
            [GPSAltitude] => 255/1
            [GPSTimeStamp] => Array
                (
                    [0] => 9/1
                    [1] => 37/1
                    [2] => 30/1
                )

            [GPSMapDatum] => WGS-84
            [GPSDateStamp] => 2011:01:29
        )

)

私の質問は、配列の 2 次元または 3 次元にある場合でも、選択したキーのみをキーと値のペアとして表示する関数を作成するにはどうすればよいかということです。

たとえば、上記の配列から、[ImageWidth] , [ImageLength] , [XResolution] , [GPSTimeStamp] and [GPSLatitude] ..

私はそれを次のような関数に渡します:

$keys_array = (ImageWidth , ImageLength, XResolution, GPSTimeStamp , GPSLatitude) 

その後

function select_keys_from_array ($keys_array='') {  
// if $keys_array=='' then get all ..
//identify the dimension or flatten - and get only my keys and display key/value 
}

これらのキーを例として選択したのは、それらの一部が第 2 レベルにあり、一部が実際には配列自体であるためです..

理論的にはキーを複製できる (ユーザー キー) という問題もありますが、異なる第 2 レベルの配列に存在します (したがって、名目上は複製されません)。

最初に「平坦化」してから、必要なキーの配列を何らかの方法で「渡す」必要があると思いますが、実際には正しく取得できないようです。

誰かがそのようなことのための既製のクラス/関数/スニペットを知っていますか?

4

4 に答える 4

1

多次元配列をフラットな配列に変換し、重複したキーや不要なキーを削除する再帰関数を作成します。

function multi2flat($array) 
{
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}
于 2012-03-28T07:22:35.850 に答える
1
<?

$x = Array
(
    'FILE' => Array
        (
            'FileName' => 'f-20110129_004_pp.jpg',
            'FileDateTime' => 0,
            'FileSize' => 3566966,
            'FileType' => 2,
            'MimeType' => 'image/jpeg',
            'SectionsFound' => 'ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS',
        ),

    'COMPUTED' => Array
        (
            'html' => 'width="2576" height="1936"',
            'Height' => 1936,
            'Width' => 2576,
            'IsColor' => 1,
            'ByteOrderMotorola' => 0,
            'ApertureFNumber' => 'f/2.8',
            'Thumbnail.FileType' => 2,
            'Thumbnail.MimeType' => 'image/jpeg',
        ),

    'IFD0' => Array
        (
            'ImageWidth' => 2576,
            'ImageLength' => 1936,
            'BitsPerSample' => Array
                (
                    '0' => 8,
                    '1' => 8,
                    '2' => 8,
                ),

            'Make' => 'Nokia',
            'Model' => 'N900',
            'Orientation' => 1,
            'SamplesPerPixel' => 3,
            'XResolution' => '3000000/10000',
            'YResolution' => '3000000/10000',
            'ResolutionUnit' => 2,
            'Software' => 'Adobe Photoshop CS5 Windows',
            'DateTime' => '2011:01:29 09:37:30',
            'YCbCrPositioning' => 1,
            'Exif_IFD_Pointer' => 276,
            'GPS_IFD_Pointer' => 658,
        ),

    'THUMBNAIL' => Array
        (
            'Compression' => 6,
            'XResolution' => '72/1',
            'YResolution' => '72/1',
            'ResolutionUnit' => 2,
            'JPEGInterchangeFormat' => 978,
            'JPEGInterchangeFormatLength' => 5525,
        ),

    'EXIF' => Array
        (
            'ExposureTime' => '1/500',
            'FNumber' => '14/5',
            'ExposureProgram' => 0,
            'ISOSpeedRatings' => 100,
            'ExifVersion' => '0210',
            'DateTimeOriginal' => '2011:01:29 09:37:30',
            'DateTimeDigitized' => '2011:01:29 09:37:30',
            'ShutterSpeedValue' => '8/1',
            'ApertureValue' => '297/100',
            'LightSource' => 0,
            'Flash' => 0,
            'FocalLength' => '26/5',
            'FlashPixVersion' => '0100',
            'ColorSpace' => 1,
            'ExifImageWidth' => 2576,
            'ExifImageLength' => 1936,
            'CustomRendered' => 0,
            'ExposureMode' => 0,
            'WhiteBalance' => 0,
            'DigitalZoomRatio' => '1/1',
            'SceneCaptureType' => 0,
            'GainControl' => 0,
            'Contrast' => 0,
            'Saturation' => 0,
        ),

    'GPS' => Array
        (
            'GPSVersion' => '',
            'GPSLatitudeRef' => 'N',
            'GPSLatitude' => Array
                (
                    '0' => '22/1',
                    '1' => '12937/1000',
                    '2' => '0/1',
                ),

            'GPSLongitudeRef' => 'E',
            'GPSLongitude' => Array
                (
                    '0' => '113/1',
                    '1' => '32886/1000',
                    '2' => '0/1',
                ),

            'GPSAltitudeRef' => '',
            'GPSAltitude' => '255/1',
            'GPSTimeStamp' => Array
                (
                    '0' => '9/1',
                    '1' => '37/1',
                    '2' => '30/1',
                ),

            'GPSMapDatum' => 'WGS-84',
            'GPSDateStamp' => '2011:01:29',
        ),

);

function get_values( $data, $keys ) {
    $ret = Array();
    foreach( $data as $k => $v ) {
        if( is_array( $v ) ) {
            $t = get_values( $v, $keys );
            if( is_array( $t ) && sizeOf( $t ) > 0 ) {
                $ret[$k] = $t;
            }
        } else {
            if( in_array( $k, $keys ) ) {
                $ret[ $k ] = $v;
            }
        }
    }
    return $ret;
}

print_r( get_values( $x, Array( 'ImageWidth', 'ImageLength', 'XResolution', 'GPSLatitude' ) ) );

?>

于 2012-03-28T07:45:44.267 に答える
1

免責事項;完全にテストされていない、風変わりなことをするかもしれません-それでも問題ないはずです)

最終編集; 配列値 (座標など)を除外しなかったため、最初のものの方が優れていました。

function array_by_keys_recursive(array $keys, array $array) {
    $results = array();
    foreach ($keys as $key) {
        if (isset($array[$key])) {
            $results[$key] = $array[$key];
            continue;
        }
        foreach ($array as $value) {
            if (\is_array($value)) {
                $results = \array_replace($results,
                    \array_by_keys_recursive(array($search), $value));
            }
        }
    }
    return $results;
}

テスト:

$array = array(
    'a' => 1,
    'b' => 2,
    'c' => array(
        'd' => 3,
        'e' => 4,
    ),
    'f' => 5,
    'g' => array(
        'h' => array(
            'i' => 6,
            'j' => 7,
        ),
        'k' => 8,
    ),
);

\var_dump(\array_by_keys_recursive(array('a', 'b', 'c', 'h', 'i', 'j'), $array));

結果:

array(6) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  array(2) {
    ["d"]=>
    int(3)
    ["e"]=>
    int(4)
  }
  ["h"]=>
  array(2) {
    ["i"]=>
    int(6)
    ["j"]=>
    int(7)
  }
  ["i"]=>
  int(6)
  ["j"]=>
  int(7)
}
于 2012-03-28T07:32:14.830 に答える
1

必ずしもフラット化する必要はありません。実際、フラット化すると、複数のサブ配列に表示される可能性があると述べたキーが上書きされる可能性があります。再帰を使用して、ネストされた配列を含む配列を正常にウォークできる必要があるだけです (ルーチンは単一の配列を最初から最後まで読み取りますが、サブ配列に遭遇するたびにそれ自体を再帰的に呼び出します)。このように歩けるようになったら、遭遇したキーと必要なキーを単純に比較できます。

複数の場所に表示される特定のバージョンのキーが必要な場合は、何らかの方法でそれらを修飾 (「スコープ」) する必要があります。たとえば、Height だけでなく COMPUTED.Height を使用します。ウォーキング アルゴリズムは、この比較を可能にするために、配列内のパス (つまり、そこまでたどり着くまでにたどった親配列チェーン) を追跡する必要があります。

于 2012-03-28T07:24:06.807 に答える