How OpenScreen Calculates and Applies Aspect Ratios for Different Export Dimensions

OpenScreen converts user-selected aspect ratio labels into numeric values, computes even-pixel dimensions that preserve the selected ratio, and passes these values directly to the GIF or MP4 encoder constructors.

OpenScreen is an open-source video editing application that supports exporting edited videos as GIF or MP4 files while maintaining precise aspect ratio control. According to the siddharthvaddem/openscreen source code, the implementation follows a three-step pipeline: converting labels to numeric ratios, calculating even-pixel dimensions based on export format constraints, and applying those dimensions to the encoder pipeline.

Converting Aspect Ratio Labels to Numeric Values

Before calculating export dimensions, OpenScreen normalizes user-facing aspect ratio labels into numeric values. In src/utils/aspectRatioUtils.ts, the getAspectRatioValue helper maps standard labels like "16:9" or "1:1" to their decimal equivalents (16/9 or 1.0), while getNativeAspectRatioValue computes the ratio dynamically from the source video dimensions and any active crop region (lines 19-36).

This normalization ensures that downstream dimension calculations operate on consistent floating-point numbers rather than string identifiers, enabling precise mathematical alignment across both GIF and MP4 export paths.

import {
  getAspectRatioValue,
  getNativeAspectRatioValue,
  type AspectRatio,
} from '@/utils/aspectRatioUtils';

const ratio: number =
  aspectRatio === 'native'
    ? getNativeAspectRatioValue(videoWidth, videoHeight, cropRegion)
    : getAspectRatioValue(aspectRatio);

Calculating Export Dimensions for GIF Files

For GIF exports, dimension calculation centers on user-selected size presets. The calculateOutputDimensions function in src/lib/exporter/gifExporter.ts selects a target height from the preset configuration, derives the proportional width using width = height × aspectRatioValue, and forces both dimensions to even integers using the internal toEven helper (lines 59-96).

Even-pixel alignment is mandatory for GIF encoders to prevent chroma subsampling errors and ensure proper rendering across all decoders.

import { calculateOutputDimensions } from '@/lib/exporter/gifExporter';

const { width, height } = calculateOutputDimensions(
  sourceWidth,
  sourceHeight,
  gifSizePreset,
  GIF_SIZE_PRESETS,
  aspectRatioValue,          // numeric ratio from step above
);

Calculating Export Dimensions for MP4 Files

MP4 exports handle dimension calculation differently depending on whether the user selects source quality or a fixed-height preset. Both paths reside in src/components/video-editor/VideoEditor.tsx and enforce even-pixel constraints to satisfy video codec requirements.

Source Quality Dimension Calculation

When exporting at source quality, OpenScreen iterates downward from the original video dimensions in 2-pixel steps to locate the largest even pair that satisfies the target ratio within a tolerance of 0.0001. For landscape videos (ratio > 1), the algorithm iterates the width; for portrait videos, it iterates the height (lines 42-73).

// source-quality path (exact match to source dimensions)
let exportWidth = Math.floor(sourceWidth / 2) * 2;
let exportHeight: number;

if (aspectRatioValue > 1) {
  // Landscape
  for (let w = exportWidth; w >= 100; w -= 2) {
    const h = Math.round(w / aspectRatioValue);
    if (h % 2 === 0 && Math.abs(w / h - aspectRatioValue) < 0.0001) {
      exportWidth = w;
      exportHeight = h;
      break;
    }
  }
} else {
  // Portrait
  exportHeight = Math.floor(sourceHeight / 2) * 2;
  for (let h = exportHeight; h >= 100; h -= 2) {
    const w = Math.round(h * aspectRatioValue);
    if (w % 2 === 0 && Math.abs(w / h - aspectRatioValue) < 0.0001) {
      exportWidth = w;
      break;
    }
  }
}

Preset Quality Dimension Calculation

For medium (720 px) or high (1080 px) quality exports, the algorithm fixes the target height and derives the width using floor division to maintain even pixels: Math.floor((height × aspectRatioValue) / 2) × 2 (lines 84-91).

const targetHeight = exportQuality === 'medium' ? 720 : 1080;
exportHeight = Math.floor(targetHeight / 2) * 2;
exportWidth  = Math.floor((exportHeight * aspectRatioValue) / 2) * 2;

Applying Computed Dimensions to the Export Pipeline

Once calculated, the width and height values are passed directly to the exporter constructors. In VideoEditor.tsx, the handleOpenExportDialog and handleExport functions instantiate either GifExporter or VideoExporter with the computed dimensions. These values initialize the rendering pipeline and final encoder—GIF via new GIF({ width, height, … }) and MP4 via new VideoExporter({ width, height, … })—ensuring the encoded output matches the calculated aspect ratio exactly.

Summary

  • Aspect ratio normalization occurs in aspectRatioUtils.ts, converting labels like "16:9" or "native" into numeric values via getAspectRatioValue and getNativeAspectRatioValue.
  • GIF dimension calculation uses calculateOutputDimensions in gifExporter.ts to derive even-pixel widths from preset heights while preserving the target ratio.
  • MP4 dimension calculation supports two modes: iterative fitting for source quality (lines 42-73 of VideoEditor.tsx) or direct calculation for 720p/1080p presets (lines 84-91).
  • Even-pixel constraints are enforced across all export paths to ensure codec compatibility, using toEven helpers or explicit Math.floor(... / 2) * 2 rounding.
  • Pipeline initialization passes final dimensions to GifExporter and VideoExporter constructors, configuring the encoding pipeline for the specific export format.

Frequently Asked Questions

How does OpenScreen handle the "native" aspect ratio option?

When users select the native aspect ratio, OpenScreen invokes getNativeAspectRatioValue from src/utils/aspectRatioUtils.ts, which calculates the ratio based on the source video's original dimensions and any applied crop region. This numeric value then flows through the same dimension calculation pipeline used for standard ratios like 16:9 or 1:1, ensuring the export maintains the video's original proportions.

Why does OpenScreen enforce even-pixel dimensions for exports?

Video codecs and GIF encoders require dimensions to be multiples of 2 to prevent chroma subsampling errors and encoding artifacts. OpenScreen enforces this constraint through the toEven helper for GIF exports and explicit Math.floor(... / 2) * 2 rounding for MP4 exports, guaranteeing compatibility across all target formats and playback environments.

What is the difference between GIF and MP4 dimension calculation in OpenScreen?

GIF exports derive dimensions from preset-based heights (small, medium, large) using calculateOutputDimensions in gifExporter.ts, calculating widths proportionally and rounding to even values. MP4 exports offer two distinct paths in VideoEditor.tsx: an iterative algorithm for source quality that searches for the largest even dimensions matching the original resolution, or a direct calculation for fixed 720p/1080p heights with proportional widths.

How does the source quality algorithm maintain aspect ratio fidelity?

The source quality implementation in VideoEditor.tsx iterates downward from the original video dimensions in 2-pixel increments, testing each candidate pair against the target ratio with a strict tolerance of 0.0001. This iterative search ensures the exported video preserves the selected aspect ratio exactly while maximizing resolution and adhering to even-pixel constraints required by the encoder.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →