◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-03-14中級

Rork Max カメラ・ギャラリー機能ガイド — 写真撮影と画像選択を実装する

Rork Maxでカメラアクセスとギャラリー機能を実装する方法です。写真の撮影、画像の選択、最適化とキャッシング、ユーザー体験を高める工夫、パフォーマンスのベストプラクティス、他の認証機能との連携までを順に解説します。SNSやECアプリに応用できる内容です。

rork-max41cameragallerynative-apiimage-handling

Rork Maxカメラ・ギャラリー機能ガイド

モバイルアプリケーションにおいて、カメラアクセスとギャラリー機能は不可欠な要素です。ユーザーが写真を撮影したり、デバイスに保存された画像を選択したりする機能は、SNSアプリ、ECアプリ、ドキュメント管理アプリなど、様々な場面で活用されています。

ネイティブAPIの活用から画像最適化まで、実践的な実装方法をカバーします。

カメラ機能の基本実装

パーミッション設定の重要性

Rork Maxでカメラを使用する際、まず必要なのはパーミッションの設定です。iOSではInfo.plistに、AndroidではAndroidManifest.xmlに、カメラとマイク使用の許可を明記する必要があります。

import { Camera } from 'react-native-vision-camera';
import { useState } from 'react';
 
export function CameraScreen() {
  const [hasPermission, setHasPermission] = useState(false);
 
  // パーミッション要求
  const requestCameraPermission = async () => {
    try {
      const status = await Camera.requestCameraPermission();
      setHasPermission(status === 'granted');
      console.log(`カメラパーミッション: ${status}`);
      // 期待出力: カメラパーミッション: granted
    } catch (error) {
      console.error('パーミッション要求エラー:', error);
    }
  };
 
  return (
    <div>
      <button onClick={requestCameraPermission}>
        カメラを有効化
      </button>
      {hasPermission && <p>カメラが利用可能です</p>}
    </div>
  );
}

このコード例では、ユーザーからカメラ使用の許可を取得しています。パーミッション取得はアプリの初期化時に実行することが推奨されます。

ギャラリー機能の実装

画像選択機能

ユーザーが既存の画像を選択する機能は、react-native-image-pickerなどのライブラリを活用して実装できます。

import ImagePicker from 'react-native-image-picker';
import { useState } from 'react';
 
export function GallerySelector() {
  const [selectedImage, setSelectedImage] = useState(null);
 
  const pickImage = async () => {
    const options = {
      mediaType: 'photo',
      quality: 0.8,
      maxWidth: 1920,
      maxHeight: 1440,
    };
 
    ImagePicker.launchImageLibrary(options, (response) => {
      if (response.didCancel) {
        console.log('画像選択がキャンセルされました');
      } else if (response.error) {
        console.error('ギャラリーエラー:', response.error);
      } else {
        setSelectedImage(response.assets[0]);
        console.log(`選択画像: ${response.assets[0].fileName}`);
        // 期待出力: 選択画像: photo_2026_03_14.jpg
      }
    });
  };
 
  return (
    <div>
      <button onClick={pickImage}>ギャラリーから選択</button>
      {selectedImage && (
        <img
          src={selectedImage.uri}
          alt="Selected"
          style={{ maxWidth: '300px' }}
        />
      )}
    </div>
  );
}

画像最適化とキャッシング

撮影・選択後の画像処理

高解像度の画像をそのままアップロードするとネットワーク負荷が増加します。画像圧縮・リサイズ処理を導入することで、UX向上とストレージ効率化を実現できます。

import ImageResizer from 'react-native-image-resizer';
 
export async function optimizeImage(imagePath) {
  try {
    const resizedImage = await ImageResizer.createResizedImage(
      imagePath,
      1200,  // 幅
      900,   // 高さ
      'JPEG',
      85,    // 品質 (1-100)
      0      // 回転
    );
 
    console.log(`最適化完了: ${resizedImage.size} bytes`);
    // 期待出力: 最適化完了: 245000 bytes
    return resizedImage;
  } catch (error) {
    console.error('画像最適化エラー:', error);
  }
}

このプロセスにより、オリジナル画像を約50-70%削減できます。

ユーザー体験の向上

プログレス表示とエラーハンドリング

大きなファイルのアップロード時は、ユーザーに進捗を表示する点が肝心です。

export function ImageUploadWithProgress() {
  const [progress, setProgress] = useState(0);
  const [isUploading, setIsUploading] = useState(false);
 
  const uploadImage = async (imagePath) => {
    setIsUploading(true);
    const xhr = new XMLHttpRequest();
 
    xhr.upload.addEventListener('progress', (e) => {
      if (e.lengthComputable) {
        const percentComplete = (e.loaded / e.total) * 100;
        setProgress(percentComplete);
        console.log(`アップロード進捗: ${Math.round(percentComplete)}%`);
      }
    });
 
    xhr.addEventListener('load', () => {
      setIsUploading(false);
      console.log('アップロード完了');
      // 期待出力: アップロード完了
    });
 
    // アップロード実行 (省略)
  };
 
  return (
    <div>
      {isUploading && <p>進捗: {Math.round(progress)}%</p>}
    </div>
  );
}

パフォーマンス最適化のベストプラクティス

メモリ管理

カメラ機能はメモリを多く消費します。以下の対策を講じましょう:

  • 画像キャッシング: 同一画像の重複読み込みを避ける
  • メモリリーク対策: コンポーネント卸載時にリソースを解放
  • バックグラウンド処理: 重い画像処理は別スレッドで実行

詳しくは、Rork Max ネイティブAPI ガイドを参照してください。

他の認証機能との連携

ユーザープロフィール画像の設定などは、認証システムと連携します。詳細はRork Max ソーシャルログイン実装ガイドをご覧ください。

また、アニメーション効果を加えた画像プレビューについては、Rork Max アニメーション・ジェスチャーガイドで詳しく解説しています。

12年の個人開発で見えてきたこと

リリース直後にチェックしているもの

  • クラッシュレポートの上位エラーを24時間ごとに確認しているか
  • AdMob/StoreKit の収益ダッシュボードに異常検知が出ていないか
  • ユーザーレビューに技術的な指摘が含まれていないか
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ 開発ツール2026-10-15
EXPO_PUBLIC_ の値が、開発では読めて本番だけ undefined になる書き方を、変換結果で見分けます
API の URL が開発中は読めるのに、ビルドした途端に undefined になる。原因は process.env の書き方でした。babel-preset-expo の変換結果を開発・本番で並べ、置き換わる書き方と残ってしまう書き方を表にしました。
⬡ 開発ツール2026-10-14
起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、読み込みより先に過ぎていたためです
Android 版の起動広告が、アプリを完全に終了してから開く回だけ一度も出ていませんでした。「前面に戻った」合図を読み込みの完了と切り離し、順番ごとにテストできる形へ組み直した記録です。
⬡ 開発ツール2026-10-13
リリース前に、書き出した Expo バンドルの中から自分の鍵を探してみる
ソースに鍵がなくても、出来上がったアプリの中に鍵が残ることがあります。Expo SDK 57 で実際に expo export を実行し、バンドルの中身を grep と 60 行ほどの Node スクリプトで調べて、見つかる鍵と見つからない鍵の違いを確かめました。