mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
Improve image compression (#2369)
* added options * added checkbox handling to import into note * added image compression option respecting
This commit is contained in:
parent
de20183a22
commit
886fdf7cd6
@ -1,6 +1,7 @@
|
|||||||
import utils from '../services/utils.js';
|
import utils from '../services/utils.js';
|
||||||
import treeService from "../services/tree.js";
|
import treeService from "../services/tree.js";
|
||||||
import importService from "../services/import.js";
|
import importService from "../services/import.js";
|
||||||
|
import options from "../services/options.js";
|
||||||
|
|
||||||
const $dialog = $("#import-dialog");
|
const $dialog = $("#import-dialog");
|
||||||
const $form = $("#import-form");
|
const $form = $("#import-form");
|
||||||
@ -8,6 +9,7 @@ const $noteTitle = $dialog.find(".import-note-title");
|
|||||||
const $fileUploadInput = $("#import-file-upload-input");
|
const $fileUploadInput = $("#import-file-upload-input");
|
||||||
const $importButton = $("#import-button");
|
const $importButton = $("#import-button");
|
||||||
const $safeImportCheckbox = $("#safe-import-checkbox");
|
const $safeImportCheckbox = $("#safe-import-checkbox");
|
||||||
|
const $shrinkImagesWrapper = $("shrink-images-wrapper");
|
||||||
const $shrinkImagesCheckbox = $("#shrink-images-checkbox");
|
const $shrinkImagesCheckbox = $("#shrink-images-checkbox");
|
||||||
const $textImportedAsTextCheckbox = $("#text-imported-as-text-checkbox");
|
const $textImportedAsTextCheckbox = $("#text-imported-as-text-checkbox");
|
||||||
const $codeImportedAsCodeCheckbox = $("#code-imported-as-code-checkbox");
|
const $codeImportedAsCodeCheckbox = $("#code-imported-as-code-checkbox");
|
||||||
@ -21,7 +23,7 @@ export async function showDialog(noteId) {
|
|||||||
$fileUploadInput.val('').trigger('change'); // to trigger Import button disabling listener below
|
$fileUploadInput.val('').trigger('change'); // to trigger Import button disabling listener below
|
||||||
|
|
||||||
$safeImportCheckbox.prop("checked", true);
|
$safeImportCheckbox.prop("checked", true);
|
||||||
$shrinkImagesCheckbox.prop("checked", true);
|
$shrinkImagesCheckbox.prop("checked", options.is('compressImages'));
|
||||||
$textImportedAsTextCheckbox.prop("checked", true);
|
$textImportedAsTextCheckbox.prop("checked", true);
|
||||||
$codeImportedAsCodeCheckbox.prop("checked", true);
|
$codeImportedAsCodeCheckbox.prop("checked", true);
|
||||||
$explodeArchivesCheckbox.prop("checked", true);
|
$explodeArchivesCheckbox.prop("checked", true);
|
||||||
|
@ -3,6 +3,13 @@ import server from "../../services/server.js";
|
|||||||
import toastService from "../../services/toast.js";
|
import toastService from "../../services/toast.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
|
<style>
|
||||||
|
.disabled-field {
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4>Spell check</h4>
|
<h4>Spell check</h4>
|
||||||
|
|
||||||
@ -27,15 +34,22 @@ const TPL = `
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4>Image compression</h4>
|
<h4>Image compression</h4>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="image-max-width-height">Max width / height of an image in pixels (image will be resized if it exceeds this setting).</label>
|
<input id="image-compresion-enabled" type="checkbox" name="image-compression-enabled">
|
||||||
<input class="form-control" id="image-max-width-height" type="number">
|
<label for="image-compresion-enabled">Enable image compression</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div id="image-compression-enabled-wraper">
|
||||||
<label for="image-jpeg-quality">JPEG quality (0 - worst quality, 100 best quality, 50 - 85 is recommended)</label>
|
<div class="form-group">
|
||||||
<input class="form-control" id="image-jpeg-quality" min="0" max="100" type="number">
|
<label for="image-max-width-height">Max width / height of an image in pixels (image will be resized if it exceeds this setting).</label>
|
||||||
|
<input class="form-control" id="image-max-width-height" type="number">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="image-jpeg-quality">JPEG quality (0 - worst quality, 100 best quality, 50 - 85 is recommended)</label>
|
||||||
|
<input class="form-control" id="image-jpeg-quality" min="0" max="100" type="number">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -201,6 +215,26 @@ export default class ProtectedSessionOptions {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.$enableImageCompression = $("#image-compresion-enabled");
|
||||||
|
this.$imageCompressionWrapper = $("#image-compression-enabled-wraper");
|
||||||
|
|
||||||
|
this.setImageCompression = (isChecked) => {
|
||||||
|
if (isChecked) {
|
||||||
|
this.$imageCompressionWrapper.removeClass("disabled-field");
|
||||||
|
} else {
|
||||||
|
this.$imageCompressionWrapper.addClass("disabled-field");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$enableImageCompression.on("change", () => {
|
||||||
|
const isChecked = this.$enableImageCompression.prop("checked");
|
||||||
|
const opts = { 'compressImages': isChecked ? 'true' : 'false' };
|
||||||
|
|
||||||
|
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
|
||||||
|
|
||||||
|
this.setImageCompression(isChecked);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
optionsLoaded(options) {
|
optionsLoaded(options) {
|
||||||
@ -216,5 +250,9 @@ export default class ProtectedSessionOptions {
|
|||||||
|
|
||||||
this.$autoReadonlySizeText.val(options['autoReadonlySizeText']);
|
this.$autoReadonlySizeText.val(options['autoReadonlySizeText']);
|
||||||
this.$autoReadonlySizeCode.val(options['autoReadonlySizeCode']);
|
this.$autoReadonlySizeCode.val(options['autoReadonlySizeCode']);
|
||||||
|
|
||||||
|
const compressImages = options['compressImages'] === 'true';
|
||||||
|
this.$enableImageCompression.prop('checked', compressImages);
|
||||||
|
this.setImageCompression(compressImages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ const ALLOWED_OPTIONS = new Set([
|
|||||||
'dailyBackupEnabled',
|
'dailyBackupEnabled',
|
||||||
'weeklyBackupEnabled',
|
'weeklyBackupEnabled',
|
||||||
'monthlyBackupEnabled',
|
'monthlyBackupEnabled',
|
||||||
'maxContentWidth'
|
'maxContentWidth',
|
||||||
|
'compressImages'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function getOptions() {
|
function getOptions() {
|
||||||
|
@ -14,6 +14,7 @@ const isSvg = require('is-svg');
|
|||||||
const isAnimated = require('is-animated');
|
const isAnimated = require('is-animated');
|
||||||
|
|
||||||
async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
|
async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
|
||||||
|
const compressImages = optionService.getOptionBool("compressImages");
|
||||||
const origImageFormat = getImageType(uploadBuffer);
|
const origImageFormat = getImageType(uploadBuffer);
|
||||||
|
|
||||||
if (origImageFormat && ["webp", "svg", "gif"].includes(origImageFormat.ext)) {
|
if (origImageFormat && ["webp", "svg", "gif"].includes(origImageFormat.ext)) {
|
||||||
@ -25,7 +26,7 @@ async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
|
|||||||
shrinkImageSwitch = false;
|
shrinkImageSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalImageBuffer = shrinkImageSwitch ? await shrinkImage(uploadBuffer, originalName) : uploadBuffer;
|
const finalImageBuffer = (compressImages && shrinkImageSwitch) ? await shrinkImage(uploadBuffer, originalName) : uploadBuffer;
|
||||||
|
|
||||||
const imageFormat = getImageType(finalImageBuffer);
|
const imageFormat = getImageType(finalImageBuffer);
|
||||||
|
|
||||||
|
@ -90,7 +90,8 @@ const defaultOptions = [
|
|||||||
{ name: 'dailyBackupEnabled', value: 'true', isSynced: false },
|
{ name: 'dailyBackupEnabled', value: 'true', isSynced: false },
|
||||||
{ name: 'weeklyBackupEnabled', value: 'true', isSynced: false },
|
{ name: 'weeklyBackupEnabled', value: 'true', isSynced: false },
|
||||||
{ name: 'monthlyBackupEnabled', value: 'true', isSynced: false },
|
{ name: 'monthlyBackupEnabled', value: 'true', isSynced: false },
|
||||||
{ name: 'maxContentWidth', value: '1200', isSynced: false }
|
{ name: 'maxContentWidth', value: '1200', isSynced: false },
|
||||||
|
{ name: 'compressImages', value: 'true', isSynced: true }
|
||||||
];
|
];
|
||||||
|
|
||||||
function initStartupOptions() {
|
function initStartupOptions() {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox" id="shrink-images-wrapper">
|
||||||
<label data-toggle="tooltip" title="<p>If you check this option, Trilium will attempt to shrink the imported images by scaling and optimization which may affect the perceived image quality. If unchecked, images will be imported without changes.</p><p>This doesn't apply to <code>.zip</code> imports with metadata since it is assumed these files are already optimized.</p>">
|
<label data-toggle="tooltip" title="<p>If you check this option, Trilium will attempt to shrink the imported images by scaling and optimization which may affect the perceived image quality. If unchecked, images will be imported without changes.</p><p>This doesn't apply to <code>.zip</code> imports with metadata since it is assumed these files are already optimized.</p>">
|
||||||
<input id="shrink-images-checkbox" value="1" type="checkbox" checked> <span>Shrink images</span>
|
<input id="shrink-images-checkbox" value="1" type="checkbox" checked> <span>Shrink images</span>
|
||||||
</label>
|
</label>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user