スポンサーリンク

ネコが撮影できるスマホアプリを作ろうと思う その8 ギャラリー機能を追加

スマホアプリ
スポンサーリンク

撮れた画像が見られるように

meowsnapSnapMeow ネコを自動で撮影する自撮りカメラ
Get it on Google Play

前の記事にて、猫カフェに実際に行って改善点が見つかったので、さっそく2点の改善を行いました。

ネコが撮影できるスマホアプリを作ろうと思う その7 猫カフェで実験
猫も撮らずにアプリだけは公開している状態 SnapMeow ネコを自動で撮影する自撮りカメラ この猫の撮影用アプリ、公開してから何と僕自身は一度もネコを撮らないまま結構日にちが経っ...

カメラをフロントカメラからバックカメラに

フロントカメラにすることで、猫が自分の動画を見るようになってこっちを向いてくれるかなという狙いがあったんだけど、そんなことは全然なくてネコは全然興味持ちませんでした。

それなら、動画は人間が見て構図を確認した方が良いし、カメラも高画素の物を使った方が良いので、バックカメラを使う事にしました。
Screenshot_2016-05-06-10-02-16

ギャラリー機能を追加

もう一つの機能追加は撮影された画像の一覧表示と選択によって一枚が拡大されて表示されるギャラリーの追加。

一覧表示はこんな感じです。
Screenshot_2016-05-06-10-02-35
そのうちの1つを選択すると、こんな感じで画面に拡大して表示されます。
Screenshot_2016-05-06-10-02-49

内部ストレージのフォルダの画像を一覧表示する方法

ここからは技術的な話。

このアプリは、スマホの内部のストレージのSnapMeowフォルダに画像を保存していくんですけど、その画像を一覧表示する方法です。
画像を一覧表示する機能についてはこちらを参考にさせてもらいました。

[Android] GridView 作り方使い方

まず、ギャラリー用のActivityをGalleryActivityとして以下のように作成します。

public class GallaryActivity extends Activity {
    ImageView sendButton;
    GridView gridview;
    GridAdapter adapter;
    
    String sdPath;
    private File[] files;
    private static final String PHOTO_FOLDER = "/SnapMeow/";
    // 要素をArrayListで設定
    private List<String> imgList = new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery);


        sendButton = (ImageView) findViewById(R.id.camera_button);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        // GridViewのインスタンスを生成
        gridview = (GridView) findViewById(R.id.gridview);
        // BaseAdapter を継承したGridAdapterのインスタンスを生成
        // 子要素のレイアウトファイル grid_items.xml を main.xml に inflate するためにGridAdapterに引数として渡す
        adapter = new GridAdapter(this.getApplicationContext(), R.layout.grid_items, imgList);
        // gridViewにadapterをセット
        gridview.setAdapter(adapter);

        sdPath = Environment.getExternalStorageDirectory().getPath() + PHOTO_FOLDER;
        files = new File(sdPath).listFiles();

        getImagePath();

        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String item = sdPath + files[position].getName();
                Log.d("path", String.format("%s", item));
                showItem(item);
            }
        });
    }
    //拡大表示のActivity用のIntent
    public void showItem(String str){
        Intent intent = new Intent(getApplication(), FullimageActivity.class);
        intent.putExtra("filename",str);
        startActivity(intent);
    }
    private void getImagePath() {

        String destPath = null;
        for(int i=0; i< files.length ; i++) {
            //jpgファイルだけをリストに入れる
            if (files[i].isFile() && files[i].getName().endsWith(".jpg")) {
                destPath = sdPath + files[i].getName();
                // List<String> imgList にはファイルのパスを入れる
                imgList.add(destPath);
            }
        }
    }

    class ViewHolder {
        ImageView imageView;
    }

    class GridAdapter extends BaseAdapter {
        private LayoutInflater inflater;
        private int layoutId;

        public GridAdapter(Context context,  int layoutId, List<String> imgList) {
            super();
            this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            this.layoutId = layoutId;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            String mFilepath = imgList.get(position);

            ViewHolder holder;
            if (convertView == null) {
                // gallery.xml の <GridView .../> に grid_items.xml を inflate して convertView とする
                convertView = inflater.inflate(layoutId, parent, false);
                // ViewHolder を生成
                holder = new ViewHolder();
                holder.imageView = (ImageView) convertView.findViewById(R.id.imageview);
                convertView.setTag(holder);
            }
            else {
                holder = (ViewHolder) convertView.getTag();
            }

            Bitmap bmp = BitmapFactory.decodeFile(mFilepath);
            holder.imageView.setImageBitmap(bmp);

            return convertView;
        }

        @Override
        public int getCount() {
            // List<String> imgList の全要素数を返す
            return imgList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }
    }
}

次に、レイアウトファイルとして、gallery.xmlとgrid_items.xmlを作成します。gallery.xmlはギャラリー全体のレイアウトで、grid_items.xmlは一覧表示の時の一枚の画像のレイアウトになります。

gallery.xml
ポイントはlayout_weight=”1″としている事で、こうしておくと下部にボタンやGoogle Adsenseなどのバナーを固定させてスクロールさせることができます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              xmlns:ads="http://schemas.android.com/apk/res-auto"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000000"
        android:gravity="center"
        android:horizontalSpacing="1dp"
        android:verticalSpacing="1dp"
        android:numColumns="4"
        android:stretchMode="columnWidth"
        android:layout_weight="1"/>

</LinearLayout>

grid_items.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="100dp"
              android:background="#ffffff"
              android:gravity="center"
              android:padding="3dp" >

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter" />

</LinearLayout>

そして、次は一枚の拡大表示用のFullimageActivityを以下のように作成します。拡大表示用のxmlは特筆することはないので割愛。

public class FullimageActivity  extends Activity {
    ImageView backButton;
    String filename;
   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fullimage);
        
        Intent intentget = getIntent();
        //一覧表示から送られてきたファイルまでのフルパス名を受け取る    
        filename = intentget.getStringExtra("filename");
        File srcFile = new File(filename);
        Bitmap bm =null;
        ImageView iv = (ImageView) findViewById(R.id.imageView_photo);

        try {
            InputStream is = new FileInputStream(srcFile);
            bm = BitmapFactory.decodeStream(is);
            iv.setImageBitmap(bm);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        backButton = (ImageView) findViewById(R.id.imageView_back);
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //←アイコンを押したら一覧表示に戻る
                finish();
            }
        });
    }
}

これで、ギャラリー機能が実装できます。

自撮り棒とのペアで超強力に

このアプリの良い所は、ネコの前にスマホを差し出しさえすれば勝手に撮影してくれるので、撮影のためにネコを見つめる必要がない所です。このおかげでネコが緊張したり怖がったりすることがなく、自然な表情を撮影することができます。

勝手に撮ってくれる機能を応用して自撮り棒を使えば、今までのカメラでは取りにくい場所、例えば高い所にいる場合、床に寝そべっている場合も無理な姿勢にならなくても撮ることができます。

もう1つの利点として、自分の飼い猫ももちろん撮れるんですが、それよりも街で見かけたネコを撮るのに向いてます。普通のカメラだとネコを観てないと撮れないですが、これは目線を外して撮れるんで、野良ネコ撮影にピッタリです。

このアプリに関する記事一覧はこちらから。

ネコが撮影できるスマホアプリを作ろうと思う 記事一覧
猫を自動で認識して撮影するアプリ 完成したアプリはこちらです、アンドロイドのみの対応となりますが、カメラをネコに向けると自動でネコの顔を認識して画像を保存していきます。 SnapMeow ...
スマホアプリ
スポンサーリンク
スポンサーリンク
良いなと思ったら、シェアしてください
このブログをフォローする
Findelight

コメント