Skip to content

Latest commit

Β 

History

History
587 lines (458 loc) Β· 13.7 KB

File metadata and controls

587 lines (458 loc) Β· 13.7 KB

πŸ“· Book Cover Scanner - Complete Guide

Overview

The Book Cover Scanner is a prototype feature that allows users to scan physical book covers using their device camera to instantly find and preview audiobooks. This is currently a frontend-only implementation with mock data, designed to be easily integrated with a backend image recognition system.


🎯 Features Implemented

βœ… 1. Camera Access UI

  • "Scan Book Cover" button in navigation
  • Live camera preview using browser's getUserMedia API
  • Works on both mobile and desktop (uses back camera on mobile)
  • Visual scan frame to guide users where to position the book

βœ… 2. Mock Capture Flow

  • Capture button to take a photo
  • Canvas-based image capture from video stream
  • Image data stored as base64 for future API upload
  • Simulated processing with loading animation

βœ… 3. Preview Result Screen

  • Match found confirmation with success animation
  • Book details display: Title, Author, Cover, Description
  • "Play Preview" button (ready for audio integration)
  • "View Full Book" button (navigates to book page)
  • "Scan Another" button to restart process

βœ… 4. Error Handling

  • Camera permission denied error state
  • Retry mechanism for camera access
  • User-friendly error messages
  • Fallback navigation to home page

βœ… 5. Backend Integration Placeholders

  • Detailed TODO comments in code
  • Mock API structure ready for real implementation
  • Image data capture ready for upload
  • Comprehensive integration guide in comments

πŸ“ Files Created

Lisbook/
β”œβ”€β”€ scan.html          # Main scanner page
β”œβ”€β”€ scan.css           # Scanner-specific styles
β”œβ”€β”€ scan.js            # Camera logic and mock processing
└── SCANNER_GUIDE.md   # This documentation

πŸš€ How It Works (User Flow)

Step 1: Access Scanner

  1. User clicks "Scan Book" in navigation
  2. Lands on scan.html with instructions

Step 2: Start Scanning

  1. User clicks "Start Scanning" button
  2. Browser requests camera permission
  3. If granted β†’ Camera preview appears
  4. If denied β†’ Error state with retry option

Step 3: Capture Image

  1. User positions book cover in the scan frame
  2. User clicks "Capture" button
  3. Image is captured from video stream
  4. Camera stops automatically

Step 4: Processing (Mock)

  1. Processing animation shows for 2 seconds
  2. In production: Image would be sent to backend API
  3. Currently: Random book selected from mock database

Step 5: View Result

  1. Match found screen appears
  2. Shows book cover, title, author, description
  3. User can:
    • Play audio preview
    • View full book page
    • Scan another book

πŸ’» Technical Implementation

Camera Access (getUserMedia API)

// Request camera with specific constraints
const constraints = {
    video: {
        facingMode: 'environment',  // Back camera on mobile
        width: { ideal: 1280 },
        height: { ideal: 720 }
    }
};

const stream = await navigator.mediaDevices.getUserMedia(constraints);
videoElement.srcObject = stream;

Browser Support:

  • βœ… Chrome/Edge (Desktop & Mobile)
  • βœ… Firefox (Desktop & Mobile)
  • βœ… Safari (iOS 11+)
  • ❌ Internet Explorer (not supported)

Image Capture

// Create canvas and capture current video frame
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;

const context = canvas.getContext('2d');
context.drawImage(video, 0, 0);

// Get image as base64
const imageData = canvas.toDataURL('image/jpeg', 0.8);

State Management

The scanner uses a simple state machine:

initial β†’ camera β†’ processing β†’ result
   ↓         ↓                      ↓
   β†β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              (scan again)

Each state has its own UI component that's shown/hidden via CSS classes.


πŸ”Œ Backend Integration Guide

Current Mock Implementation

// scan.js - processImage() function
function processImage(imageData) {
    // Currently: Random book selection
    const randomBook = MOCK_BOOKS[Math.floor(Math.random() * MOCK_BOOKS.length)];
    displayResult(randomBook);
}

Real Implementation (TODO)

async function processImage(imageData) {
    try {
        // 1. Send image to your backend
        const response = await fetch('https://your-api.com/api/scan-book', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer YOUR_API_KEY'
            },
            body: JSON.stringify({
                image: imageData,
                timestamp: Date.now()
            })
        });

        // 2. Get book match from response
        const result = await response.json();

        if (result.success && result.book) {
            // 3. Display the matched book
            displayResult(result.book);
        } else {
            // 4. Handle no match found
            showNoMatchError();
        }

    } catch (error) {
        console.error('API Error:', error);
        showAPIError();
    }
}

πŸ€– Recommended Backend Technologies

Option 1: Google Cloud Vision API

Best for: OCR and text detection

# Python backend example
from google.cloud import vision

def scan_book_cover(image_data):
    client = vision.ImageAnnotatorClient()
    image = vision.Image(content=image_data)
    
    # Detect text on book cover
    response = client.text_detection(image=image)
    texts = response.text_annotations
    
    # Extract title and author
    book_text = texts[0].description if texts else ""
    
    # Search in your database
    book = search_book_in_database(book_text)
    
    return book

Pros:

  • Excellent OCR accuracy
  • Handles various fonts and languages
  • Easy to integrate

Cons:

  • Requires Google Cloud account
  • Costs money after free tier

Option 2: Custom ML Model

Best for: Direct cover image recognition

# Using TensorFlow/Keras
import tensorflow as tf

# Load pre-trained model
model = tf.keras.models.load_model('book_cover_model.h5')

def identify_book(image):
    # Preprocess image
    img = preprocess_image(image)
    
    # Predict
    predictions = model.predict(img)
    book_id = np.argmax(predictions)
    
    # Get book from database
    book = get_book_by_id(book_id)
    
    return book

Pros:

  • No API costs
  • Can work offline
  • Full control

Cons:

  • Requires training data
  • Need ML expertise
  • Maintenance overhead

Option 3: ISBN Barcode Scanner

Best for: Books with visible barcodes

// Using QuaggaJS (client-side)
Quagga.init({
    inputStream: {
        type: "LiveStream",
        target: document.querySelector('#camera-preview')
    },
    decoder: {
        readers: ["ean_reader"] // ISBN barcodes
    }
}, function(err) {
    if (err) {
        console.error(err);
        return;
    }
    Quagga.start();
});

Quagga.onDetected(function(result) {
    const isbn = result.codeResult.code;
    // Look up book by ISBN
    searchBookByISBN(isbn);
});

Pros:

  • Very accurate
  • Fast recognition
  • Can run client-side

Cons:

  • Only works if barcode is visible
  • Requires good lighting
  • Limited to books with ISBNs

πŸ—„οΈ Backend API Structure

Endpoint: POST /api/scan-book

Request:

{
    "image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
    "userId": "user123",
    "timestamp": 1234567890
}

Response (Success):

{
    "success": true,
    "book": {
        "id": 1,
        "title": "Pale Blue Dot",
        "author": "Carl Sagan",
        "cover": "https://example.com/covers/pale-blue-dot.jpg",
        "description": "A vision of the human future in space...",
        "audioPreview": "https://example.com/audio/preview.mp3",
        "audioFull": "https://example.com/audio/full.mp3",
        "duration": "8:45:30",
        "rating": 4.5
    },
    "confidence": 0.95
}

Response (No Match):

{
    "success": false,
    "error": "NO_MATCH_FOUND",
    "message": "Could not identify the book cover",
    "suggestions": [
        {
            "title": "Similar Book 1",
            "confidence": 0.65
        }
    ]
}

Response (Error):

{
    "success": false,
    "error": "PROCESSING_ERROR",
    "message": "Failed to process image"
}

🎨 UI/UX Features

Animations

  • Fade in/out transitions between states
  • Pulse animation on scan frame
  • Loading spinner during processing
  • Success checkmark animation
  • Floating icons in "How It Works" section

Responsive Design

  • Mobile-first approach
  • Touch-friendly buttons
  • Adaptive camera preview size
  • Stacked layout on small screens

Accessibility

  • ARIA labels on buttons
  • Keyboard navigation support
  • Screen reader friendly
  • High contrast colors

πŸ§ͺ Testing Checklist

Desktop Testing

  • Camera access works in Chrome
  • Camera access works in Firefox
  • Camera access works in Edge
  • Capture button works
  • Cancel button stops camera
  • Result screen displays correctly
  • Navigation works

Mobile Testing

  • Back camera is used (not selfie camera)
  • Camera preview fits screen
  • Touch controls work
  • Capture is responsive
  • Result screen is readable
  • Can navigate back

Error Scenarios

  • Camera permission denied shows error
  • Retry button works
  • No camera device handled
  • Camera already in use handled

🚧 Future Enhancements

Phase 1: Basic Backend

  • Integrate Google Vision API
  • Set up backend server (Node.js/Python)
  • Create book database
  • Implement basic text recognition

Phase 2: Improved Recognition

  • Train custom ML model
  • Add ISBN barcode scanning
  • Implement fuzzy matching
  • Handle multiple language books

Phase 3: Enhanced Features

  • Save scan history
  • Share scanned books
  • Batch scanning (multiple books)
  • Offline mode with cached data

Phase 4: Advanced Features

  • AR overlay on book cover
  • Voice search integration
  • Social features (friends' libraries)
  • Recommendation engine based on scans

πŸ“Š Performance Considerations

Image Optimization

// Compress image before sending
function compressImage(imageData, maxWidth = 800) {
    const img = new Image();
    img.src = imageData;
    
    img.onload = () => {
        const canvas = document.createElement('canvas');
        const ratio = maxWidth / img.width;
        canvas.width = maxWidth;
        canvas.height = img.height * ratio;
        
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        
        return canvas.toDataURL('image/jpeg', 0.7);
    };
}

Caching Strategy

// Cache recognized books
const bookCache = new Map();

function getCachedBook(imageHash) {
    return bookCache.get(imageHash);
}

function cacheBook(imageHash, bookData) {
    bookCache.set(imageHash, bookData);
    // Limit cache size
    if (bookCache.size > 100) {
        const firstKey = bookCache.keys().next().value;
        bookCache.delete(firstKey);
    }
}

πŸ”’ Security Considerations

Client-Side

  • Validate image size before upload (max 5MB)
  • Sanitize user inputs
  • Use HTTPS only
  • Implement rate limiting

Backend

  • Authenticate API requests
  • Validate image format
  • Scan for malicious content
  • Implement CORS properly
  • Rate limit per user/IP

πŸ“ Code Comments Guide

The code includes detailed comments marking integration points:

/**
 * TODO: Backend Integration Point
 * 
 * This is where you would send the image to your backend API
 * for actual image recognition and book matching.
 */

Search for TODO in scan.js to find all integration points.


πŸŽ“ Learning Resources

Camera API

Image Recognition

Barcode Scanning


πŸ› Troubleshooting

Camera not working

Problem: Black screen or no camera preview

Solutions:

  1. Check browser permissions
  2. Ensure HTTPS (camera requires secure context)
  3. Try different browser
  4. Check if camera is used by another app

Image quality poor

Problem: Captured image is blurry

Solutions:

  1. Increase camera resolution in constraints
  2. Add autofocus support
  3. Improve lighting conditions
  4. Use image enhancement filters

Processing too slow

Problem: Long wait time after capture

Solutions:

  1. Compress image before sending
  2. Use WebWorkers for processing
  3. Implement progressive loading
  4. Cache common results

πŸ“ž Support

For questions or issues:

  1. Check this guide first
  2. Review code comments in scan.js
  3. Test in different browsers
  4. Check browser console for errors

βœ… Summary

You now have a fully functional book cover scanner prototype that:

  • βœ… Accesses device camera
  • βœ… Captures book cover images
  • βœ… Simulates book matching
  • βœ… Displays results beautifully
  • βœ… Is ready for backend integration

The code is production-ready on the frontend and just needs a backend API to make it fully functional!


Happy Scanning! πŸ“šπŸ“·