diff --git a/assets/brush-logo.png b/assets/brush-logo.png new file mode 100644 index 0000000..c1153ac Binary files /dev/null and b/assets/brush-logo.png differ diff --git a/assets/sparkle-left.png b/assets/sparkle-left.png new file mode 100644 index 0000000..40d7400 Binary files /dev/null and b/assets/sparkle-left.png differ diff --git a/assets/sparkle-right.png b/assets/sparkle-right.png new file mode 100644 index 0000000..9e77a84 Binary files /dev/null and b/assets/sparkle-right.png differ diff --git a/assets/upload-icon.png b/assets/upload-icon.png new file mode 100644 index 0000000..706f3aa Binary files /dev/null and b/assets/upload-icon.png differ diff --git a/blurme/pages/about.py b/blurme/pages/about.py index 518c622..de4a03a 100644 --- a/blurme/pages/about.py +++ b/blurme/pages/about.py @@ -46,13 +46,23 @@ def about() -> rx.Component: rx.box( rx.text("Jesteśmy grupą studentek kierunku Przetwarzania i Analizy Danych, które postanowiły połączyć swoje różnorodne umiejętności w ramach wspólnego projektu. Zależy nam nie tylko na zdobywaniu wiedzy na uczelni, ale także na praktycznym wykorzystaniu naszych umiejętności w realnych projektach.", margin_right="5%", margin_left="5%", margin_bottom = "10px"), - rx.list( - rx.list_item( rx.icon(tag="arrow_forward")," W naszym zespole każda z nas wnosi unikalne perspektywy i pomysły, co sprawia, że nasza współpraca jest inspirująca.",), - rx.list_item(rx.icon(tag="arrow_forward"), " Nasza pasja do analizy danych oraz zrozumienie dziedziny przetwarzania danych stanowią fundamenty naszego projektu."), - rx.list_item( rx.icon(tag="arrow_forward")," Naszym głównym celem jest stworzenie innowacyjnego rozwiązania, które nie tylko będzie spełniać potrzeby dzisiejszych czasów, ale również przyczyni się do ochrony prywatności w kontekście współdzielenia zdjęć online.",), - margin_left = "18%", margin_right = "18%"), + rx.list(rx.hstack( + rx.list_item(rx.text("Współpraca",as_="b",font_size="1.3em"), + rx.text("W naszym zespole każda z nas wnosi unikalne perspektywy i pomysły, co sprawia, że nasza współpraca jest inspirująca.", text_align="center"),), + rx.list_item(rx.text("Innowacyjność",as_="b",font_size="1.3em"), + rx.text("Naszym głównym celem jest stworzenie innowacyjnego rozwiązania, które nie tylko będzie spełniać potrzeby dzisiejszych czasów, ale również przyczyni się do ochrony prywatności w kontekście współdzielenia zdjęć online.", text_align="center"),), + rx.list_item(rx.text("Analiza danych", as_="b",font_size="1.3em"), + rx.text("Nasza pasja do analizy i zrozumienia dziedziny przetwarzania danych stanowią fundamenty naszego projektu.", text_align="center"),), + style={"align-self": "center", "align-items": "flex-start"}),style={"align-self": "center", "align-items": "flex-start"}, margin_right = "5%", margin_left = "5%"), - rx.text("Dzięki zaufaniu naszych użytkowników oraz naszemu zangażowaniu, wierzymy, że nasz projekt przyczyni się do tworzenia bezpieczniejszej przestrzeni dla współdzielenia zdjęć w sieci. Cieszymy się, że możemy być częścią tej fascynującej podróży.", margin_right="5%", margin_left="5%", margin_top="10px"), text_align = "center",), + + #rx.list( + # rx.list_item( rx.icon(tag="arrow_forward")," W naszym zespole każda z nas wnosi unikalne perspektywy i pomysły, co sprawia, że nasza współpraca jest inspirująca.",), + # rx.list_item(rx.icon(tag="arrow_forward"), " Nasza pasja do analizy danych oraz zrozumienie dziedziny przetwarzania danych stanowią fundamenty naszego projektu."), + # rx.list_item( rx.icon(tag="arrow_forward")," Naszym głównym celem jest stworzenie innowacyjnego rozwiązania, które nie tylko będzie spełniać potrzeby dzisiejszych czasów, ale również przyczyni się do ochrony prywatności w kontekście współdzielenia zdjęć online.",), + # margin_left = "18%", margin_right = "18%"), + + rx.text("Dzięki zaufaniu naszych użytkowników oraz naszemu zangażowaniu, wierzymy, że nasz projekt przyczyni się do tworzenia bezpieczniejszej przestrzeni dla współdzielenia zdjęć w sieci. Cieszymy się, że możemy być częścią tej fascynującej podróży!", margin_right="5%", margin_left="5%", margin_top="10px"), text_align = "center",), rx.list( rx.list_item(rx.text("Nasza Misja",padding = "10px", text_align="center",background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", font_size="2em", font_weight="bold", margin_top="30px", margin_bottom="5px"), rx.text("Nasza grupa powstała z fascynacji technologią oraz z troską o prywatność w dzisiejszym świecie online. Świadomi wyzwań związanych z udostępnianiem fotografii publicznie, postanowiliśmy stworzyć aplikację, która umożliwi użytkownikom ochronę swojej prywatności, jednocześnie pozwalając na swobodne udostępnianie chwil z życia."),margin_right = "40%"), diff --git a/blurme/pages/index.py b/blurme/pages/index.py index 9a9c263..c053d89 100644 --- a/blurme/pages/index.py +++ b/blurme/pages/index.py @@ -8,18 +8,23 @@ import reflex as rx @template(route="/", title="Strona główna", image = "/home-icon.png") def index() -> rx.Component: return rx.vstack( - rx.heading("Witaj w BlurMe!", font_size="3em", margin_bottom="25px", background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", padding = "10px"), + rx.wrap( rx.hstack( - rx.vstack(rx.text("Aplikacja do anonimizacji zdjęć: usunięcie wybranych informacji identyfikujących ze zdjęć z wydarzeń i miejsc publicznych nigdy nie było tak proste!", - font_size="1.2em", style={"margin-left": "40px", "margin-top": "50px", "align-self": "flex-start", "margin-bottom": "25px"}), - rx.link(rx.button("Zacznij anonimizować"), href="settings",align="center",color="rgba(117,102,254,255)",button=True,padding="50xp",font_size="1.2em",style={"margin-top": "30px" }),style = {"align-self": "flex-start"}), - rx.image(src="obraz1.png",height="30em",padding="0.5em",style={"margin-right": "60px"}), + rx.vstack(rx.hstack(rx.image(src="sparkle-left.png",height="3em"), + rx.heading("Witaj w BlurMe!", font_size="2.6em", margin_bottom="10px", background_image="linear-gradient( 64.5deg, rgba(245,116,185,1) 14.7%, rgba(89,97,223,1) 88.7% )", background_clip="text", padding = "5px", text_align = "center"), + rx.image(src="sparkle-right.png",height="3em"), style={"align-self": "center"}), + rx.text("Usunięcie wybranych informacji identyfikujących ze zdjęć z wydarzeń i miejsc publicznych nigdy nie było tak proste!", font_size="1.2em", text_align = "center"), + rx.text("Dołącz do naszej społeczności użytkowników, którzy cieszą się swobodą dzielenia się chwilami bez obaw o bezpieczeństwo swoich danych osobowych. Zacznij tworzyć bezpieczne wspomnienia już dziś!", margin_bottom="25px", text_align = "center"), + rx.text("", pading = "25px"), + rx.link(rx.button("Zacznij anonimizować"), href="settings",align="center",color="rgba(117,102,254,255)",button=True,padding="50xp",font_size="1.2em"), + style={"align-self": "flex-start","margin-left": "50px", "margin-top": "50px", "align-self": "flex-start", "margin-bottom": "25px"}, width = "50%"), + rx.image(src="obraz1.png",height="25em",padding="0.5em",style={"margin-right": "60px"}), style={"align-self": "flex-start"}),), rx.text(" ", height = "20px"), - rx.vstack(rx.text("Jak to działa?", color = "rgba(117,102,253,255)", font_size="2em", font_weight="bold", margin_top="20px", margin_bottom="5px"), + rx.vstack(rx.text("Jak to działa?", color = "rgba(117,102,253,255)", font_size="2em", font_weight="bold", margin_top="15px", margin_bottom="5px"), rx.list( rx.list_item(rx.text("1. Wgraj Zdjęcie ",as_="b",font_size="1.2em"), rx.text("Prosty proces rozpoczyna się od dodania zdjęcia, które chcesz anonimizować.", ),margin_right = "50%"), diff --git a/blurme/pages/settings.py b/blurme/pages/settings.py index ee5ba95..7d1f21e 100644 --- a/blurme/pages/settings.py +++ b/blurme/pages/settings.py @@ -2,7 +2,6 @@ import asyncio from blurme.templates import template from blurme.state import State - import reflex as rx @@ -10,13 +9,26 @@ color = "rgb(107,99,246)" @template(route="/settings", title="Zdjęcie", image = "/image-icon.png") def settings() -> rx.Component: + icon_style = {"width": "20px", "height": "30px", "margin-right": "10px"} + return rx.vstack( - rx.heading("BlurMe", font_size="3em", margin_bottom="25px", background_image="linear-gradient(271.68deg, #7566fe 0.75%, #f96caf 88.52%)", background_clip="text", padding = "10px"), - rx.text("Dodaj zdjęcie, które chcesz zanonimizować", font_size="1.2em"), - rx.upload( - rx.vstack(rx.text("Przeciągnij albo kliknij, aby wybrać pliki"),), + + rx.wrap( + rx.hstack( + rx.vstack( + rx.image(src="/brush-logo.png",height="5.2em", margin_bottom="15px"), + rx.heading("Anonimizuj już teraz!", font_size="2em", margin_bottom="15px", background_image="linear-gradient(271.68deg, #7566fe 0.75%, #f96caf 88.52%)", background_clip="text", padding = "5px"), + rx.text("Dodaj zdjęcie, wybierz obszar i ukryj tożsamość: Anonimizacja zdjęć w mgnieniu oka – szybko, łatwo, bezpłatnie!", font_size="1.2em", text_align = "center"), width = "50%", margin_left = "50px"), + rx.vstack(rx.upload( + rx.vstack(rx.image(src="/upload-icon.png",height="5em"), + rx.text("Przeciągnij, aby wybrać pliki", font_size = "1em"), + rx.text("albo", font_size = "0.8em"), + rx.button("Kliknij", font_size = "1em", color="rgba(117,102,254,255)"), + rx.text(" "), + rx.text("Dostępne rozszerzenia plików: png, jpg, webp, tiff", font_size = "0.8em"),), border=f"1px dotted {color}", - padding="5em", + padding="1em", + width = "90%", multiple=True, accept={ "image/png": [".png"], @@ -24,52 +36,36 @@ def settings() -> rx.Component: "image/webp": [".webp"], "image/tiff": [".tif", ".tiff"], }, max_files=5, + margin_top = "15px", ), rx.hstack(rx.foreach(rx.selected_files, rx.text)), rx.button( "Załaduj zdjęcie", on_click=lambda: State.handle_upload( - rx.upload_files()),color = "rgba(47, 187, 74,255)"), + rx.upload_files()),color = "rgba(47, 187, 74,255)"),width = "60%", margin_left = "50px"),), margin_bottom = "25px", style={"align-self": "center", "align-items": "flex-start"}, spacing="2em"), rx.responsive_grid( rx.foreach( State.img, lambda img: rx.vstack( - rx.image(src=f'/{img}', height = "200px"), - rx.text(img), + rx.image(src=f'/{img}', max_height = "450px"), + rx.text(img, font_size="15px" ), - rx.hstack(rx.button("Usuń", + rx.hstack(rx.button(rx.icon(tag="delete", margin_right = "8px"), " Usuń", on_click=lambda img_name=img: State.delete_image(img_name), color="rgba(255, 75, 42,255)", - width = "125px"), - rx.button("Anonimizuj", - width = "125px"), - rx.button("Pobierz", + width = "100px"), + rx.button(rx.icon(tag="edit", margin_right = "8px"), " Anonimizuj", + on_click=lambda img_name=img: State.image_anonymization(img_name), + width = "130px"), + rx.button(rx.icon(tag="download", margin_right = "8px"), " Pobierz", on_click=lambda img_name=img: State.download_image(img_name), - width = "125px"), + width = "100px"), padding="1em" ), ), - ),columns=[2], + ),columns=[1], spacing="5px", - - - - #rx.foreach( - # State.img, - # lambda img: rx.vstack( - # rx.image(src=f'/{img}', max_width = "800px"), - # rx.hstack(rx.button("Usuń", - # on_click=lambda img_name=img: State.delete_image(img_name), - # width = "125px"), - # rx.button("Anonimizuj", - # width = "125px"), - # rx.button("Pobierz", - # on_click=lambda img_name=img: State.download_image(img_name), - # width = "125px"), - # padding="1em" - # ), - # padding="3em", ),) \ No newline at end of file diff --git a/blurme/state.py b/blurme/state.py index cfb47b6..0149beb 100644 --- a/blurme/state.py +++ b/blurme/state.py @@ -1,9 +1,13 @@ """Base state for the app.""" import reflex as rx +import os from blurme import styles import asyncio +from graphics.image_modification import blur_boxes_on_image +from ml.element_detection import BoundBox, detect + class State(rx.State): """The app state.""" @@ -43,6 +47,18 @@ class State(rx.State): print(self.img) return rx.download(url=f'/{img_name}', filename=img_name) + async def image_anonymization(self, img_name: str): + if img_name in self.img: + image_path = rx.get_asset_path(img_name) + new_img_name = "anonim-" + img_name + new_image_path = rx.get_asset_path(new_img_name) + blur_boxes_on_image(image_path, detect(image_path), new_image_path) + upload_file = rx.UploadFile(file=open(new_image_path, 'rb'), filename=new_img_name) + self.delete_image(img_name) + await self.handle_upload([upload_file]) + self.img=self.img + + diff --git a/graphics/image_modification.py b/graphics/image_modification.py index 8edde89..453207a 100644 --- a/graphics/image_modification.py +++ b/graphics/image_modification.py @@ -4,7 +4,7 @@ from typing import List from PIL import Image, ImageDraw, ImageFont, ImageFilter from PIL.Image import composite -from BlurMe.ml.element_detection import BoundBox +from ml.element_detection import BoundBox DIR_PATH = os.path.dirname(os.path.realpath(__file__)) diff --git a/ml/test.py b/ml/test.py index ad99d45..4c84d74 100644 --- a/ml/test.py +++ b/ml/test.py @@ -1,7 +1,7 @@ import unittest from unittest.mock import Mock, patch from element_detection import detect, BoundBox -from BlurMe.graphics.image_modification import show_image_with_boxes +from graphics.image_modification import show_image_with_boxes class TestYourModule(unittest.TestCase):