2015年9月12日土曜日

iOSから送られてくるバイナリ画像(base64エンコードされた画像)をfuelphpでS3にアップロードする的なお話

  • このエントリーをはてなブックマークに追加

なんかアプリとかそういうのを作っていると、画像をサーバに送信したいとかそういうときがある。
そういうときは画像をサーバ上というかS3上に保存する必要があるんだけど、
これってwebサイトのinput type="file"とは違ってファイルがそのまんま送られるわけではないのそう単純なことではなかったりする。
バイナリというかバイナリ文字列がポストされてくるみたいな。

で、そのバイナリを保存してさらに拡張子を付ける必要があるんだけど、簡単にやろうというのが今回のお話。
一応fuelphpでって書いてあるけどfuelphpを使ってる部分は少ないので、
PHPでちゃんとプログラムを書ける人であればしっかりと理解出来るんじゃないか的なお話をば。

public function save_img($_binary = null,$_dir = "img"){
  if(is_null($_binary)){
    echo "error";
    return false;
  }

  if(is_null($_dir)){
    echo "error";
    return false;
  }

  /* check */
  $image_file = trim(str_replace(array("<",">",' '),'',$_binary));

  $finfo = finfo_open(FILEINFO_MIME_TYPE);
  $mime_type = finfo_buffer($finfo, $image_file);
  finfo_close($finfo);

  $mime_type = NULL;
  if(strncmp("\x89PNG\x0d\x0a\x1a\x0a",$image_file,8) == 0 || strncmp("89504e",$image_file,6) == 0){
    $mime_type = 'image/png';
  }
  elseif(strncmp('BM',$image_file,2) == 0){
    $mime_type = 'image/bmp';
  }
  elseif(strncmp('GIF87a',$image_file,6) == 0 || strncmp('GIF89a',$image_file,6) == 0){
    $mime_type = 'image/gif';
  }
  elseif(strncmp("\xff\xd8",$image_file,2) == 0 || strncmp("ffd8ff",$image_file,6) == 0){
    $mime_type = 'image/jpeg';
  }
  else{
    $mime_type = NULL;
  }

  switch($mime_type){
    case "image/gif":
      $img_extension = ".gif";
      break;
    case "image/jpeg":
    case "image/jpg":
      $img_extension = ".jpg";
      break;
    case "image/png":
      $img_extension = ".png";
      break;
    default:
      $img_extension = "";
      break;
  }

  $img_name = \Str::random('unique');
  $result = \S3::put_object(hex2bin($image_file),"bucket-name","{$_dir}/{$img_name}{$img_extension}","public-read",array(),$mime_type);

  return $result?$img_name.$img_extension:false;
}
こんな感じでfunctionを作ってあげればよい。
どこかでクラスで保存してもいいし、なんなら普通のPHPでもrequireするfunction群の一つに入れてもよい。
肝となるのが/* check */以下部分からswitch前までで、ここで送られてきた文字列の拡張子判別をしている。
細かいルールを説明するのが面倒だけど、拡張子によってバイナリ文字列の先頭が決まっているので、それを判別。
で、それらに応じて拡張子を付けてあげて、適当な名前をつけてS3上に保存してあげる的な。
ちなみにfuelphpでS3上にファイルを保存する的な記事はこちら

ってな感じでiOSからバイナリ文字列が送られてきたら画像として保存する事が出来る。
Androidでは試してないけど多分同じような感じじゃないのかなと勝手に思ってみたり。

Adsense