Full Stack Software Developer

Laravel input capture live camera

I was working on a project which required direct upload of image from mobile camera. But due to mimetype being sent as octate it had issues and also file was being returned as empty.

The only possible solution that worked was to store the base64 code of the image in a textarea then on post save the encoded code as file.

Everything else seems to have failed. Anyone used any better approach ? I have implemented my solution on Laravel framework.

Find chatgpt generated code given below that implements the logic:

<form method="POST" action="{{ route('media.store') }}" enctype="multipart/form-data">
    @csrf

    <div>
        <label for="file_upload">Upload Image(s)</label>
        <input type="file" name="file_uploads[]" multiple accept="image/*">
    </div>

    <div class="mt-4">
        <label>Live Camera Feed</label><br>
        <video id="camera" autoplay playsinline width="300"></video><br>
        <button type="button" onclick="captureAndAttach()">Capture and Attach</button>
        <div id="snapshots" class="mt-2"></div>
        <!-- captures[] will be appended here -->
    </div>

    <div class="mt-4">
        <label for="label">Label</label>
        <input type="text" name="label" required>
    </div>

    <div class="mt-4">
        <label for="attachable_type">Attachable Type</label>
        <input type="text" name="attachable_type" value="App\\Models\\Product" required>
    </div>

    <div class="mt-4">
        <label for="attachable_id">Attachable ID</label>
        <input type="number" name="attachable_id" required>
    </div>

    <button type="submit" class="mt-4 bg-blue-500 text-white px-4 py-2">Submit</button>
</form>

<canvas id="canvas" style="display: none;"></canvas>

<script>
    const video = document.getElementById('camera');
    const canvas = document.getElementById('canvas');
    const snapshots = document.getElementById('snapshots');

    navigator.mediaDevices.getUserMedia({ video: true })
        .then((stream) => {
            video.srcObject = stream;
        });

    function captureAndAttach() {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        const context = canvas.getContext('2d');
        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        const base64 = canvas.toDataURL('image/png');

        const textarea = document.createElement('textarea');
        textarea.name = 'captures[]';
        textarea.style.display = 'none';
        textarea.value = base64;

        const preview = document.createElement('img');
        preview.src = base64;
        preview.width = 100;
        preview.classList.add('inline-block', 'mr-2', 'mb-2');

        snapshots.appendChild(preview);
        snapshots.appendChild(textarea);
    }
</script>
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;
use App\Models\Media;

public function store(Request $request)
{
    $request->validate([
        'label' => 'required|string',
        'attachable_type' => 'required|string',
        'attachable_id' => 'required|integer',
    ]);

    // Handle uploaded files
    if ($request->hasFile('file_uploads')) {
        foreach ($request->file('file_uploads') as $file) {
            $path = $file->store('uploads', 'public');

            Media::create([
                'label' => $request->label,
                'link' => $path,
                'attachable_type' => $request->attachable_type,
                'attachable_id' => $request->attachable_id,
            ]);
        }
    }

    // Handle base64 captures
    if ($request->filled('captures')) {
        foreach ($request->captures as $capture) {
            $image = str_replace('data:image/png;base64,', '', $capture);
            $image = str_replace(' ', '+', $image);
            $filename = 'capture_' . uniqid() . '.png';
            Storage::disk('public')->put("uploads/{$filename}", base64_decode($image));

            Media::create([
                'label' => $request->label,
                'link' => "uploads/{$filename}",
                'attachable_type' => $request->attachable_type,
                'attachable_id' => $request->attachable_id,
            ]);
        }
    }

    return back()->with('success', 'Media uploaded successfully!');
}

Faisal Ahmed
Wev Application Developer
https://www.faisalbd.com

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.