Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: blurry start mode #8

Merged
merged 3 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"manifest_version": 3,
"name": "HumanBlur",
"description": "Protect your privacy and uphold Islamic values by auto detecting & blurring images and videos of unwanted or impermissible content.",
"version": "0.0.1",
"version": "0.0.2",
"permissions": ["activeTab", "storage"],
"author": "[email protected]",
"action": {
"default_title": "HumanBlur",
"default_popup": "src/popup.html"
Expand All @@ -18,14 +19,14 @@
"content_scripts": [
{
"js": ["dist/content.js"],
"matches": ["<all_urls>"],
"matches": ["https://*/*", "http://*/*"],
"run_at": "document_start"
}
],
"web_accessible_resources": [
{
"resources": ["src/assets/models/*"],
"matches": ["<all_urls>"]
"matches": ["https://*/*", "http://*/*"]
}
]
}
Binary file removed src/assets/models/blazeface-front.bin
Binary file not shown.
196 changes: 0 additions & 196 deletions src/assets/models/blazeface-front.json

This file was deleted.

Binary file added src/assets/models/blazeface.bin
Binary file not shown.
292 changes: 292 additions & 0 deletions src/assets/models/blazeface.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const defaultSettings = {
status: true,
blurryStartMode: false,
blurAmount: 15,
blurImages: true,
blurVideos: true,
Expand All @@ -18,6 +19,11 @@ chrome.runtime.onInstalled.addListener(function () {
result["hb-settings"] === null
) {
chrome.storage.sync.set({ "hb-settings": defaultSettings });
} else {
// if there are any new settings, add them to the settings object
chrome.storage.sync.set({
"hb-settings": { ...defaultSettings, ...result["hb-settings"] },
});
}
});
});
33 changes: 20 additions & 13 deletions src/content.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { human, initHuman } from "./modules/detector";
import { emitEvent } from "./modules/helpers";
import { attachObserversListener } from "./modules/observers";
import {
getSettings,
Expand All @@ -7,33 +8,39 @@ import {
} from "./modules/settings";
import { attachStyleListener } from "./modules/style";

Promise.all([initHuman(), getSettings()])
const attachAllListeners = () => {
// Listen for more settings
listenForMessages();
attachStyleListener();
attachObserversListener();
};

attachAllListeners();
getSettings()
.then(() => {
// console.log("HB==HUMAN LOADED", "HB==SETTINGS LOADED", human);
// console.log("HB==SETTINGS LOADED");
emitEvent("settingsLoaded");

// init human
return initHuman();
})
.then(() => {
// console.log("HB==HUMAN INITIALIZED", human);

// wait for the dom to load
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
// console.log("HB==DOM LOADED");
// turn on/off the extension
attachAllListeners();
toggleOnOffStatus();
});
} else {
// console.log("HB==DOM ALREADY LOADED", document.readyState);
attachAllListeners();

// turn on/off the extension
toggleOnOffStatus();
}
})
.catch((err) => {
console.error("HB==ERROR", err);
.catch((e) => {
console.log("HB==INITIALIZATION ERROR", e);
});

const attachAllListeners = () => {
attachStyleListener();
attachObserversListener();
// Listen for more settings
listenForMessages();
};
7 changes: 3 additions & 4 deletions src/modules/detector.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ const HUMAN_CONFIG = {
mesh: { enabled: false},
emotion: { enabled: false },
detector: {
modelPath: "blazeface-front.json",
modelPath: "blazeface.json",
maxDetected: 2,
rotation: true,
},
description: {
enabled: true,
Expand All @@ -45,9 +44,9 @@ const HUMAN_CONFIG = {

let human;

const initHuman = async () => {
const initHuman = () => {
human = new Human(HUMAN_CONFIG);
await human.load();
return human.load();
};

// export the human variable and the HUMAN_CONFIG object
Expand Down
31 changes: 14 additions & 17 deletions src/modules/helpers.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
const MAX_IMG_HEIGHT = 300;
const MAX_IMG_WIDTH = 500;
const MIN_IMG_WIDTH = 50;
const MIN_IMG_HEIGHT = 80;
const MIN_IMG_WIDTH = 64;
const MIN_IMG_HEIGHT = 64;
// maintain 1920x1080 aspect ratio
const MAX_VIDEO_WIDTH = 1920 / 4;
const MAX_VIDEO_HEIGHT = 1080 / 4;
const MAX_VIDEO_WIDTH = 1920 / 3.5;
const MAX_VIDEO_HEIGHT = 1080 / 3.5;

const loadImage = (img) => {
return new Promise((resolve, reject) => {
if (img.complete && img.naturalHeight) {
resolve();
isImageTooSmall(img) ? reject() : resolve();
} else {
img.onload = () => img.naturalHeight && resolve();

img.onerror = (e) => {
reject(e);
}
img.onload = () =>
img.naturalHeight
? isImageTooSmall(img)
? reject()
: resolve()
: reject();
img.onerror = (e) => reject(e);
}
});
};
Expand All @@ -39,11 +41,7 @@ const loadVideo = (video) => {
};

const isImageTooSmall = (img) => {
const isSmall =
img.width < MIN_IMG_WIDTH || img.height < MIN_IMG_HEIGHT;
if (isSmall) {
return true;
}
return img.width < MIN_IMG_WIDTH || img.height < MIN_IMG_HEIGHT;
};

const calcResize = (element, type = "image") => {
Expand Down Expand Up @@ -92,7 +90,7 @@ const processNode = (node, callBack) => {
node?.childNodes?.forEach((child) => processNode(child, callBack));
};

const emitEvent = (eventName, detail) => {
const emitEvent = (eventName, detail = "") => {
const event = new CustomEvent(eventName, { detail });
document.dispatchEvent(event);
};
Expand All @@ -104,7 +102,6 @@ const listenToEvent = (eventName, callBack) => {
export {
loadImage,
loadVideo,
isImageTooSmall,
calcResize,
hasBeenProcessed,
processNode,
Expand Down
2 changes: 1 addition & 1 deletion src/modules/observers.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const attachObserversListener = () => {
initIntersectionObserver();
initMutationObserver();
} else {
console.log("HB== Observers Listener", "disconnecting");
// console.log("HB== Observers Listener", "disconnecting");
intersectionObserver?.disconnect();
mutationObserver?.disconnect();
}
Expand Down
13 changes: 11 additions & 2 deletions src/modules/processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { human } from "./detector.js"; // import the human variable from detecto
import {
loadImage,
loadVideo,
isImageTooSmall,
calcResize,
hasBeenProcessed,
emitEvent,
} from "./helpers.js";
import {
shouldDetect,
Expand All @@ -20,6 +20,8 @@ import {

const FRAME_LIMIT = 1000 / 30; // 30 fps

let detectionStarted = false;

const genderPredicate = (gender, score) => {
if (shouldDetectMale && shouldDetectFemale) return gender !== "unknown";

Expand All @@ -37,6 +39,10 @@ const genderPredicate = (gender, score) => {
};

const processImageDetections = async (detections, img) => {
if (!detectionStarted) {
detectionStarted = true;
emitEvent("detectionStarted");
}
if (!detections?.face?.length) {
// img.dataset.blurred = "no face";
return;
Expand Down Expand Up @@ -68,6 +74,10 @@ const processImageDetections = async (detections, img) => {
img.classList.add("hb-blur");
};
const processVideoDetections = async (detections, video) => {
if (!detectionStarted) {
detectionStarted = true;
emitEvent("detectionStarted");
}
if (!detections?.face?.length) {
// video.dataset.blurred = "no face";

Expand Down Expand Up @@ -137,7 +147,6 @@ const processImage = async (img) => {
}

try {
if (isImageTooSmall(img)) return;
const needToResize = calcResize(img, "image");
let detections = needToResize
? await human.detect(img, {
Expand Down
17 changes: 13 additions & 4 deletions src/modules/settings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { emitEvent } from "./helpers";
import { emitEvent, listenToEvent } from "./helpers";

let settings = {};

Expand All @@ -15,8 +15,11 @@ function shouldDetect() {
return shouldDetectGender();
}

function toggleOnOffStatus() {
console.log("HB==toggleOnOffStatus", settings.status)
function isBlurryStartMode() {
return settings.blurryStartMode;
}

function setSettings() {
if (settings.status !== true) {
shouldDetectImages = false;
shouldDetectVideos = false;
Expand All @@ -26,7 +29,12 @@ function toggleOnOffStatus() {
shouldDetectMale = settings.blurMale;
shouldDetectFemale = settings.blurFemale;
}
}

function toggleOnOffStatus() {
// console.log("HB==toggleOnOffStatus", settings.status)

setSettings();
// console.log("HB==toggleOnOffStatus", settings.status);
emitEvent("toggleOnOffStatus", settings.status);
}
Expand All @@ -41,6 +49,7 @@ function getSettings() {
}

function listenForMessages() {
listenToEvent("settingsLoaded", setSettings)
chrome.runtime.onMessage.addListener(function (
request,
sender,
Expand Down Expand Up @@ -74,4 +83,4 @@ const changeBlurAmount = () => {
emitEvent("changeBlurAmount", settings.blurAmount);
};

export { settings, getSettings, toggleOnOffStatus, listenForMessages, shouldDetect, shouldDetectGender, shouldDetectImages, shouldDetectVideos, shouldDetectMale, shouldDetectFemale};
export { settings, isBlurryStartMode, getSettings, toggleOnOffStatus, listenForMessages, shouldDetect, shouldDetectGender, shouldDetectImages, shouldDetectVideos, shouldDetectMale, shouldDetectFemale};
48 changes: 43 additions & 5 deletions src/modules/style.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
// style.js
// This module exports the style sheet and blur effect functions

import { listenToEvent } from "./helpers.js";
import { settings, shouldDetect } from "./settings.js";
import { emitEvent, listenToEvent } from "./helpers.js";
import { settings, shouldDetect, isBlurryStartMode } from "./settings.js";

let hbStyleSheet;
const BLURRY_START_MODE_TIMEOUT = 4000; // TODO: make this a setting maybe?
let hbStyleSheet, blurryStartStyleSheet;

const initStylesheet = () => {
const initStylesheets = () => {
// console.log("HB==INIT STYLESHEETS")
hbStyleSheet = document.createElement("style");
hbStyleSheet.id = "hb-stylesheet";
document.head.appendChild(hbStyleSheet);
initBlurryMode();
};

const initBlurryMode = () => {
if (!shouldDetect() || !isBlurryStartMode()) return;
blurryStartStyleSheet = document.createElement("style");
blurryStartStyleSheet.id = "hb-blurry-start-stylesheet";
blurryStartStyleSheet.innerHTML = `
img, video{
filter: blur(${settings.blurAmount}px) grayscale(100%) !important;
transition: filter 0.1s ease !important;
opacity: unset !important;
}

img:hover, video:hover{
filter: blur(0px) grayscale(0%) !important;
transition: filter 0.5s ease !important;
transition-delay: 0.5s !important;
}
`;

document.head.appendChild(blurryStartStyleSheet);

// issue event turn off blurry start mode after 1 second
setTimeout(() => {
if (!blurryStartStyleSheet?.innerHTML) return; // if blurryStartStyleSheet wasn't instantiated/was removed, return
emitEvent("blurryStartModeTimeout", "timeout");
}, BLURRY_START_MODE_TIMEOUT);
};

const setStyle = () => {
// console.log("HB==SET STYLE")
if (!hbStyleSheet) {
initStylesheet();
initStylesheets();
}
if (!shouldDetect()) {
hbStyleSheet.innerHTML = "";
Expand Down Expand Up @@ -57,9 +87,17 @@ const setStyle = () => {
`;
};

const turnOffBlurryStart = (e) => {
if (!blurryStartStyleSheet?.innerHTML) return; // if blurryStartStyleSheet wasn't instantiated/was removed, return
blurryStartStyleSheet.innerHTML = "";
};

const attachStyleListener = () => {
listenToEvent("settingsLoaded", initStylesheets);
listenToEvent("toggleOnOffStatus", setStyle);
listenToEvent("changeBlurAmount", setStyle);
listenToEvent("detectionStarted", turnOffBlurryStart);
listenToEvent("blurryStartModeTimeout", turnOffBlurryStart);
};

export { attachStyleListener };
Loading