
Have you ever needed to include a 360° image in a PDF while allowing users to annotate specific areas? Whether you're working with real estate, construction reports, virtual tours, or educational material, embedding panoramic images inside PDFs can create a dynamic and interactive experience.
In this guide, we’ll walk through how to render a 360° panoramic image in a PDF using Ruby on Rails, JavaScript, and PDF annotation tools.
How Does It Work?
Since PDFs do not natively support 360° interactive images, we’ll take an alternative approach:
- Convert the 360° image into a panoramic (equirectangular) format.
- Embed the panoramic image inside a PDF using Rails and JavaScript.
- Allow users to add annotations (comments, highlights, and drawings).
- Export the annotated PDF for sharing and collaboration.
Step 1: Setting Up the Rails Application
We’ll start with a Ruby on Rails backend to handle PDF generation and image uploads.
Install Required Gems
Add these gems to your Gemfile for handling PDFs and images:
gem 'prawn' # For PDF generation
gem 'prawn-svg' # For embedding images
gem 'mini_magick' # For image processing
Run - bundle install
Step 2: Uploading a 360° Image
We’ll allow users to upload a 360° image, which will be processed into a panoramic format.
Generate the Upload Model
rails generate model ImageUpload file:string
rails db:migrate
Add Image Uploads Using Active Storage
Modify app/models/image_upload.rb:
class ImageUpload < ApplicationRecord
has_one_attached :file
end
Allow users to upload images through a form in app/views/uploads/new.html.erb:
<%= form_with(model: @image_upload, url: uploads_path, local: true, multipart: true) do |form| %>
<%= form.file_field :file %>
<%= form.submit "Upload 360° Image" %>
<% end %>
Handle the upload in the controller app/controllers/uploads_controller.rb:
class UploadsController < ApplicationController
def create
@image_upload = ImageUpload.new
@image_upload.file.attach(params[:image_upload][:file])
if @image_upload.save
redirect_to edit_upload_path(@image_upload)
else
render :new
end
end
end
Step 3: Displaying the 360° Image with Panoramic Viewer
Since PDFs cannot handle interactive 360° images, we’ll render a flat equirectangular projection in the web browser using panolens.js.
Install Panolens.js
Include Panolens.js in app/javascript/packs/application.js:
import 'panolens';
Create a viewer in app/views/uploads/edit.html.erb:
<div id="panorama-container"></div>
<script>
const panorama = new PANOLENS.ImagePanorama('<%= url_for(@image_upload.file) %>');
const viewer = new PANOLENS.Viewer({ container: document.getElementById('panorama-container') });
viewer.add(panorama);
</script>
➡ This will display the 360° image inside the browser.
Step 4: Annotating the Panoramic Image
We’ll allow users to annotate the image before exporting it to a PDF.
Integrate Annotorious for Annotations
Install Annotorious in app/javascript/packs/application.js:
import '@recogito/annotorious';
Modify edit.html.erb to include annotation support:
<img id="panoramic-image" src="<%= url_for(@image_upload.file) %>" width="800" />
<script>
const img = document.getElementById('panoramic-image');
const anno = Annotorious.init({ image: img });
// Save annotations
anno.on('createAnnotation', function(annotation) {
console.log('Annotation created:', annotation);
});
anno.on('updateAnnotation', function(annotation) {
console.log('Annotation updated:', annotation);
});
</script>
✅ Now users can draw, highlight, and comment on the image before exporting it.
Step 5: Exporting the Panoramic Image as a PDF
Generate PDF with Annotations
Modify app/controllers/uploads_controller.rb to include PDF generation:
require 'prawn'
class UploadsController < ApplicationController
def export_pdf
image_upload = ImageUpload.find(params[:id])
pdf = Prawn::Document.new
pdf.text "360° Image with Annotations", size: 20, style: :bold
pdf.image StringIO.new(image_upload.file.download), fit: [500, 300]
send_data pdf.render, filename: "annotated_360_image.pdf", type: "application/pdf"
end
end
Add a download button in edit.html.erb:
<%= link_to "Download PDF", export_pdf_upload_path(@image_upload), class: "btn btn-primary" %>
Final Result: Interactive PDF with 360° Annotations 🎉
✅ Users can upload a 360° image.
✅ They can annotate specific areas using Annotorious.
✅ The panoramic image (with annotations) is exported as a PDF.
This workflow allows you to transform static PDFs into immersive, annotated experiences—perfect for real estate, architecture, e-learning, and more!