84 lines
1.8 KiB
TypeScript
84 lines
1.8 KiB
TypeScript
import { Plugin } from "obsidian";
|
|
|
|
interface Color {
|
|
r: number;
|
|
g: number;
|
|
b: number;
|
|
}
|
|
|
|
export default class SVGView extends Plugin {
|
|
async onload() {
|
|
this.registerMarkdownPostProcessor((element, context) => {
|
|
const images = element.querySelectorAll("img");
|
|
|
|
images.forEach((item) => {
|
|
if (!item.src.startsWith("data:image/svg+xml")) {
|
|
// Exclude image who aren't SVG
|
|
return;
|
|
}
|
|
|
|
/** Convert to grayscale */
|
|
const colorToGrayscale = (color: Color) => {
|
|
return 0.3 * color.r + 0.59 * color.g + 0.11 * color.b;
|
|
};
|
|
|
|
/** Extract color using canvas2d */
|
|
const extractColors = (image: HTMLImageElement) => {
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = image.width;
|
|
canvas.height = image.height;
|
|
|
|
const ctx = canvas.getContext("2d");
|
|
if (!ctx) {
|
|
return;
|
|
}
|
|
|
|
ctx.drawImage(image, 0, 0);
|
|
const imageData = ctx.getImageData(
|
|
0,
|
|
0,
|
|
Math.max(1, canvas.width),
|
|
Math.max(1, canvas.height)
|
|
);
|
|
const pixelData = imageData.data;
|
|
|
|
const colors: Color[] = [];
|
|
for (let i = 0; i < pixelData.length; i += 4) {
|
|
if (pixelData[i + 3] > 0) {
|
|
colors.push({
|
|
r: pixelData[i],
|
|
g: pixelData[i + 1],
|
|
b: pixelData[i + 2],
|
|
});
|
|
}
|
|
}
|
|
|
|
return colors;
|
|
};
|
|
|
|
// Extract colors
|
|
const colors = extractColors(item);
|
|
if (!colors) {
|
|
return;
|
|
}
|
|
|
|
// Calculate the average grayscale value
|
|
const grayscaleValues = colors.map(colorToGrayscale);
|
|
const totalGrayscale = grayscaleValues.reduce(
|
|
(acc, val) => acc + val,
|
|
0
|
|
);
|
|
const averageGrayscale =
|
|
totalGrayscale / grayscaleValues.length;
|
|
|
|
if (averageGrayscale < 128) {
|
|
item.setCssStyles({
|
|
filter: "invert(1)",
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
onunload() {}
|
|
}
|