Skip to content

Instantly share code, notes, and snippets.

@JudahSan
Created November 7, 2023 17:19
Show Gist options
  • Select an option

  • Save JudahSan/e5695887175452cd70574b37fa2767a1 to your computer and use it in GitHub Desktop.

Select an option

Save JudahSan/e5695887175452cd70574b37fa2767a1 to your computer and use it in GitHub Desktop.
Image Preview and Thumbnail

Node.js

If you want to generate an image preview from any URL provided by the user, you can use a service like "Puppeteer" in combination with "Express" (or another web framework) in a separate backend server. Puppeteer is a Node.js library that provides a high-level API to control headless browsers, which can be used to generate screenshots or thumbnails of web pages.

Here's a general outline of how you can achieve this:

  1. Set Up a Backend Server: Create a separate backend server using Express.js (or any other Node.js web framework). Install the necessary packages:

    npm install express puppeteer
  2. Create an API Endpoint: Set up an API endpoint that accepts a URL and generates an image preview of the web page associated with that URL using Puppeteer.

    const express = require('express');
    const puppeteer = require('puppeteer');
    
    const app = express();
    const port = 3000;
    
    app.get('/generate-image', async (req, res) => {
      const { url } = req.query;
    
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto(url);
      const screenshot = await page.screenshot();
      await browser.close();
    
      res.set('Content-Type', 'image/png');
      res.send(screenshot);
    });
    
    app.listen(port, () => {
      console.log(`Server is running on port ${port}`);
    });

    In this example, the /generate-image endpoint accepts a url query parameter, navigates to the specified URL using Puppeteer, takes a screenshot, and sends the image back in the response.

  3. Frontend Integration: In your Rails frontend application, you can make a request to the backend server's /generate-image endpoint whenever a user submits a URL. You can use JavaScript to make an AJAX request or fetch the image in the frontend and display it to the user.

    For example, using JavaScript's fetch API:

    const inputUrl = 'https://example.com'; // Get the URL from user input
    fetch(`/generate-image?url=${encodeURIComponent(inputUrl)}`)
      .then(response => response.blob())
      .then(blob => {
        const imageUrl = URL.createObjectURL(blob);
        const imgElement = document.createElement('img');
        imgElement.src = imageUrl;
        document.body.appendChild(imgElement);
      })
      .catch(error => console.error('Error:', error));

    Replace 'https://example.com' with the actual URL provided by the user. This code fetches the image from the backend endpoint and appends it to the body of the HTML document.

Remember to handle errors, input validation, and security measures like sanitizing user input to prevent potential security vulnerabilities when working with user-provided URLs.

To add an image upload feature to your Rails application, you can use the popular gem called CarrierWave along with Amazon S3 for storage. CarrierWave allows you to easily handle file uploads in Rails applications.

Here's a step-by-step guide to integrating CarrierWave and Amazon S3 with your Rails app:

Prerequisites:

  1. Set Up an Amazon S3 Bucket:

  2. Install CarrierWave: Add CarrierWave gem to your Gemfile:

    gem 'carrierwave'

    Run bundle install to install the gem.

Configuration:

  1. Configure CarrierWave: Generate an uploader using the following command:

    rails generate uploader Image

    This will create an ImageUploader in the app/uploaders directory.

    Inside the ImageUploader class, configure it to use Amazon S3 as the storage provider:

    # app/uploaders/image_uploader.rb
    class ImageUploader < CarrierWave::Uploader::Base
      storage :fog
    
      # Amazon S3 Configuration
      config.fog_credentials = {
        provider: 'AWS',
        aws_access_key_id: 'YOUR_AWS_ACCESS_KEY_ID',
        aws_secret_access_key: 'YOUR_AWS_SECRET_ACCESS_KEY',
        region: 'YOUR_AWS_REGION'
      }
      config.fog_directory = 'YOUR_S3_BUCKET_NAME'
    end

    Make sure to replace 'YOUR_AWS_ACCESS_KEY_ID', 'YOUR_AWS_SECRET_ACCESS_KEY', 'YOUR_AWS_REGION', and 'YOUR_S3_BUCKET_NAME' with your actual Amazon S3 credentials and bucket information.

  2. Add Image Column to Your Model: In your Rails model where you want to store images, add a column for storing the image file location. For example, if you have a Post model:

    rails generate migration AddImageToPosts image:string
    rake db:migrate
  3. Update Your Model: Update your model to mount the uploader and validate the presence of the image field.

    # app/models/post.rb
    class Post < ApplicationRecord
      mount_uploader :image, ImageUploader
      validates :image, presence: true
    end

Views and Forms:

  1. Update the Form: In your form, use the file_field helper to create an input field for uploading images.
    <!-- app/views/posts/_form.html.erb -->
    <%= form_for @post, html: { multipart: true } do |f| %>
      <!-- Other form fields -->
      <%= f.file_field :image %>
      <%= f.submit 'Create Post' %>
    <% end %>

Controller:

  1. Controller Actions: Update your controller actions (e.g., new, create) to permit the :image attribute and save the uploaded image to the model.
    # app/controllers/posts_controller.rb
    class PostsController < ApplicationController
      # ...
      def create
        @post = Post.new(post_params)
        if @post.save
          redirect_to @post, notice: 'Post was successfully created.'
        else
          render :new
        end
      end
    
      private
    
      def post_params
        params.require(:post).permit(:title, :content, :image)
      end
    end

That's it! Now, your Rails application should allow users to upload images, which will be stored on Amazon S3. Remember to handle security aspects such as access control for your S3 bucket and properly securing your AWS credentials. Additionally, you might want to implement image processing, validation, and other features based on your application's requirements.

Yes, there are Ruby gems that provide similar functionality to Puppeteer for generating screenshots or thumbnails of web pages in a Ruby on Rails application. One popular gem is selenium-webdriver, which allows you to automate web browsers. Here's how you can achieve the same functionality using selenium-webdriver in a Rails application:

  1. Add Required Gem: Add the selenium-webdriver gem to your Gemfile:

    gem 'selenium-webdriver'

    Run bundle install to install the gem.

  2. Controller Action: In your Rails controller action, you can use selenium-webdriver to generate a screenshot of the provided URL. For example, assuming you have a PostsController with a generate_image action, your code might look like this:

    require 'selenium-webdriver'
    
    class PostsController < ApplicationController
      def generate_image
        url = params[:url]
        driver = Selenium::WebDriver.for :chrome
    
        driver.get(url)
        sleep(2) # Allow time for the page to load, adjust as needed
    
        screenshot = driver.save_screenshot("#{Rails.root}/public/screenshot.png")
        driver.quit
    
        send_file("#{Rails.root}/public/screenshot.png", type: 'image/png', disposition: 'inline')
      end
    end

    In this example, the generate_image action takes a URL parameter, navigates to the provided URL using Chrome browser (you'll need to have Chrome installed on your server), waits for 2 seconds to allow the page to load (you can adjust this delay as needed), takes a screenshot, saves it to the public directory, and then sends the image file in the response.

  3. Routes: Configure a route in your config/routes.rb file to map the URL to the controller action:

    Rails.application.routes.draw do
      get '/generate_image', to: 'posts#generate_image'
      # Other routes
    end
  4. Frontend Integration: In your frontend application, you can make a request to the /generate_image endpoint in a similar way as shown in the previous response. For example, using JavaScript's fetch API:

    const inputUrl = 'https://example.com'; // Get the URL from user input
    fetch(`/generate_image?url=${encodeURIComponent(inputUrl)}`)
      .then(response => response.blob())
      .then(blob => {
        const imageUrl = URL.createObjectURL(blob);
        const imgElement = document.createElement('img');
        imgElement.src = imageUrl;
        document.body.appendChild(imgElement);
      })
      .catch(error => console.error('Error:', error));

    Replace 'https://example.com' with the actual URL provided by the user.

Please note that this approach requires a headless browser (such as Chrome or Firefox) to be installed on your server where the Rails application is running. Additionally, you may need to adjust the delay before taking the screenshot to ensure the page has fully loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment