mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-14 10:34:06 +02:00
# Description of Changes - Addition of the "Adjust Colors/Contrast" tool --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
94 lines
3.3 KiB
TypeScript
94 lines
3.3 KiB
TypeScript
import React, { useEffect, useRef, useState } from 'react';
|
|
import { AdjustContrastParameters } from '../../../hooks/tools/adjustContrast/useAdjustContrastParameters';
|
|
import { useThumbnailGeneration } from '../../../hooks/useThumbnailGeneration';
|
|
import ObscuredOverlay from '../../shared/ObscuredOverlay';
|
|
import { Text } from '@mantine/core';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { applyAdjustmentsToCanvas } from './utils';
|
|
|
|
interface Props {
|
|
file: File | null;
|
|
parameters: AdjustContrastParameters;
|
|
}
|
|
|
|
export default function AdjustContrastPreview({ file, parameters }: Props) {
|
|
const { t } = useTranslation();
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
const [thumb, setThumb] = useState<string | null>(null);
|
|
const { requestThumbnail } = useThumbnailGeneration();
|
|
|
|
useEffect(() => {
|
|
let active = true;
|
|
const load = async () => {
|
|
if (!file || file.type !== 'application/pdf') { setThumb(null); return; }
|
|
const id = `${file.name}:${file.size}:${file.lastModified}:page:1`;
|
|
const tUrl = await requestThumbnail(id, file, 1);
|
|
if (active) setThumb(tUrl || null);
|
|
};
|
|
load();
|
|
return () => { active = false; };
|
|
}, [file, requestThumbnail]);
|
|
|
|
useEffect(() => {
|
|
const revoked: string | null = null;
|
|
const render = async () => {
|
|
if (!thumb || !canvasRef.current) return;
|
|
const img = new Image();
|
|
img.crossOrigin = 'anonymous';
|
|
img.src = thumb;
|
|
await new Promise<void>((resolve, reject) => {
|
|
img.onload = () => resolve();
|
|
img.onerror = () => reject();
|
|
});
|
|
|
|
// Draw thumbnail to a source canvas
|
|
const src = document.createElement('canvas');
|
|
src.width = img.naturalWidth;
|
|
src.height = img.naturalHeight;
|
|
const sctx = src.getContext('2d');
|
|
if (!sctx) return;
|
|
sctx.drawImage(img, 0, 0);
|
|
|
|
// Apply accurate pixel adjustments
|
|
const adjusted = applyAdjustmentsToCanvas(src, parameters);
|
|
|
|
// Draw adjusted onto display canvas
|
|
const display = canvasRef.current;
|
|
display.width = adjusted.width;
|
|
display.height = adjusted.height;
|
|
const dctx = display.getContext('2d');
|
|
if (!dctx) return;
|
|
dctx.clearRect(0, 0, display.width, display.height);
|
|
dctx.drawImage(adjusted, 0, 0);
|
|
};
|
|
render();
|
|
return () => {
|
|
if (revoked) URL.revokeObjectURL(revoked);
|
|
};
|
|
}, [thumb, parameters]);
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
|
|
<div style={{ flex: 1, height: 1, background: 'var(--border-color)' }} />
|
|
<div style={{ fontSize: 12, color: 'var(--text-color-muted)' }}>{t('common.preview', 'Preview')}</div>
|
|
<div style={{ flex: 1, height: 1, background: 'var(--border-color)' }} />
|
|
</div>
|
|
<ObscuredOverlay
|
|
obscured={!thumb}
|
|
overlayMessage={<Text size="sm" c="white" fw={600}>{t('adjustContrast.noPreview', 'Select a PDF to preview')}</Text>}
|
|
borderRadius={6}
|
|
>
|
|
<div ref={containerRef} style={{ aspectRatio: '8.5/11', width: '100%', border: '1px solid var(--border-color)', borderRadius: 8, overflow: 'hidden' }}>
|
|
{thumb && (
|
|
<canvas ref={canvasRef} style={{ width: '100%', height: '100%' }} />
|
|
)}
|
|
</div>
|
|
</ObscuredOverlay>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
|