From 759aa1b6844dc69d8fce2096fa5ec6e849076e69 Mon Sep 17 00:00:00 2001
From: Akshaj Rawat <159126002+akshajrawat@users.noreply.github.com>
Date: Wed, 28 Jan 2026 01:48:21 +0530
Subject: [PATCH] feat: add option to disable image anti-aliasing (#14278)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## What this PR does
Closes #13869
Adds a global setting to toggle image anti-aliasing in AFFiNE.
When disabled, images are rendered using nearest-neighbor scaling
(`image-rendering: pixelated`), preserving crisp pixels for pixel art,
sprites, icons, and low-resolution images.
## Why
Anti-aliasing causes small images to become blurry when scaled,
making it difficult to work with pixel art and technical assets.
## How to test
1. Open Settings → Appearance → Images
2. Toggle “Smooth image rendering”
3. Observe image scaling behavior:
- ON: smooth / anti-aliased
- OFF: pixelated / nearest-neighbor
## Notes
- Frontend-only change
- No backend required
# BEFORE
# AFTER
## Summary by CodeRabbit
* **New Features**
* Added an Images section in Appearance with a toggle to switch image
antialiasing on/off (setting is persisted).
* **Style**
* When antialiasing is turned off, images render with pixelated scaling
for a crisp, non-smoothed look.
* **Localization**
* Added English labels and description for the new Images and
antialiasing options.
✏️ Tip: You can customize this high-level summary in your review
settings.
---------
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
---
packages/common/infra/src/atom/settings.ts | 2 ++
.../apps/electron-renderer/src/shell/app.tsx | 1 +
.../frontend/component/src/theme/global.css | 4 ++++
.../core/src/components/context/index.tsx | 3 +++
.../components/hooks/use-image-antialiasing.ts | 12 ++++++++++++
.../general-setting/appearance/index.tsx | 17 +++++++++++++++++
.../frontend/i18n/src/i18n-completenesses.json | 8 ++++----
packages/frontend/i18n/src/i18n.gen.ts | 12 ++++++++++++
packages/frontend/i18n/src/resources/en.json | 3 +++
9 files changed, 58 insertions(+), 4 deletions(-)
create mode 100644 packages/frontend/core/src/components/hooks/use-image-antialiasing.ts
diff --git a/packages/common/infra/src/atom/settings.ts b/packages/common/infra/src/atom/settings.ts
index 8ff46461d..404cf443c 100644
--- a/packages/common/infra/src/atom/settings.ts
+++ b/packages/common/infra/src/atom/settings.ts
@@ -17,6 +17,7 @@ export type AppSetting = {
autoDownloadUpdate: boolean;
enableTelemetry: boolean;
showLinkedDocInSidebar: boolean;
+ disableImageAntialiasing: boolean;
};
export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [
'frameless',
@@ -35,6 +36,7 @@ const appSettingBaseAtom = atomWithStorage(
autoDownloadUpdate: true,
enableTelemetry: true,
showLinkedDocInSidebar: true,
+ disableImageAntialiasing: false,
},
undefined,
{
diff --git a/packages/frontend/apps/electron-renderer/src/shell/app.tsx b/packages/frontend/apps/electron-renderer/src/shell/app.tsx
index 57f9da723..24eb8d07e 100644
--- a/packages/frontend/apps/electron-renderer/src/shell/app.tsx
+++ b/packages/frontend/apps/electron-renderer/src/shell/app.tsx
@@ -32,6 +32,7 @@ export function App() {
BUILD_CONFIG.isElectron &&
environment.isMacOs &&
appSettings.enableBlurBackground;
+
return (
diff --git a/packages/frontend/component/src/theme/global.css b/packages/frontend/component/src/theme/global.css
index 7a1f3155c..249e3ec88 100644
--- a/packages/frontend/component/src/theme/global.css
+++ b/packages/frontend/component/src/theme/global.css
@@ -322,3 +322,7 @@ math {
.ai-block-diff-deleted .affine-block-component {
margin: 0 !important;
}
+
+html[data-image-antialiasing='off'] img {
+ image-rendering: pixelated;
+}
diff --git a/packages/frontend/core/src/components/context/index.tsx b/packages/frontend/core/src/components/context/index.tsx
index 2e9bec4ff..e4c64fe56 100644
--- a/packages/frontend/core/src/components/context/index.tsx
+++ b/packages/frontend/core/src/components/context/index.tsx
@@ -6,11 +6,14 @@ import { Provider } from 'jotai';
import type { PropsWithChildren } from 'react';
import { useMemo } from 'react';
+import { useImageAntialiasing } from '../hooks/use-image-antialiasing';
+
export type AffineContextProps = PropsWithChildren<{
store?: ReturnType;
}>;
export function AffineContext(props: AffineContextProps) {
+ useImageAntialiasing();
return (
{
+ document.documentElement.dataset.imageAntialiasing =
+ appSettings.disableImageAntialiasing ? 'off' : 'on';
+ }, [appSettings.disableImageAntialiasing]);
+}
diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx
index d7575a540..c7016e01c 100644
--- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx
+++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx
@@ -197,6 +197,23 @@ export const AppearanceSettings = () => {
{enableThemeEditor ? : null}
+
+
+
+ updateSettings('disableImageAntialiasing', !checked)
+ }
+ />
+
+
+
{BUILD_CONFIG.isWeb && !environment.isMobile ? (