[документация]@remove_noise.callback_query(Form.is_choosing,F.data.startswith("remove_noise"))asyncdefhandle_remove_noise(callback:CallbackQuery,state:FSMContext)->None:"""Удалить шум с изображения, начало обработки."""awaitcallback.message.answer(_("Загрузите вашу картинку (как фото или как файл)"),reply_markup=None)awaitstate.set_state(DelNoise_States.get_image)
[документация]@remove_noise.message(DelNoise_States.get_image,(F.photo)|(F.document&F.document.mime_type.startswith("image/")),)asyncdefprocess_received_image(message:Message,state:FSMContext,supabase_client:sb.Client)->None:""" Обрабатывает полученное изображение (фото или файл). Скачивает изображение, запускает ML-пайплайн для восстановления, сохраняет результат в Supabase и отправляет его пользователю. """ifmessage.photo:file_id=message.photo[-1].file_idelifmessage.document:file_id=message.document.file_idelse:awaitmessage.answer("Пожалуйста, отправьте изображение как фото или файл.")returnuser=message.from_userprocessing_msg=awaitmessage.answer(_("🔄 Ваше изображение обрабатывается..."))try:image_bytes_io=awaitmessage.bot.download(file_id)image_bytes=image_bytes_io.read()awaitprocessing_msg.edit_text(_("🔄 Обрабатываем изображение моделью..."))temp_dir=mkdtemp(prefix="inpainting_")recovered_image_np=main_model.run_inpainting_pipeline(damaged_image_source=io.BytesIO(image_bytes),output_dir=temp_dir,max_iters=250,use_gpu=True,)awaitprocessing_msg.edit_text(_("🔄 Подготавливаем результат..."))ifrecovered_image_npisNone:raiseValueError(_("Модель вернула None"))ifrecovered_image_np.dtype==np.float64:min_val=recovered_image_np.min()max_val=recovered_image_np.max()ifmax_val-min_val>0:normalized_image=(recovered_image_np-min_val)/(max_val-min_val)recovered_image_np=(255*normalized_image).astype(np.uint8)else:recovered_image_np=recovered_image_np.astype(np.uint8)iflen(recovered_image_np.shape)==3andrecovered_image_np.shape[-1]==3:recovered_image_np=cv2.cvtColor(recovered_image_np,cv2.COLOR_BGR2RGB)success,encoded_img=cv2.imencode(".jpg",recovered_image_np)ifnotsuccess:raiseValueError(_("Ошибка кодирования jpg"))processed_image_bytes=encoded_img.tobytes()file_name=f"processed_{user.id}_{uuid.uuid4().hex}.jpg"file_path=f"users/{user.id}/{file_name}"storage_response=supabase_client.storage.from_("images").upload(path=file_path,file=processed_image_bytes,file_options={"content-type":"image/jpeg"},# Указываем корректный mime-type)image_url=supabase_client.storage.from_("images").get_public_url(file_path)request_data={"created_at":datetime.datetime.now().isoformat(),"user_id":user.id,"request":"remove noise","image_url":image_url}db_response=supabase_client.table("images").insert(request_data).execute()photo_file=BufferedInputFile(file=encoded_img.tobytes(),filename="result.jpg")awaitprocessing_msg.delete()awaitmessage.answer_photo(photo=photo_file,caption=_("✅ Результат обработки"))exceptExceptionase:awaitprocessing_msg.delete()# Удаляем сообщение "обрабатывается" даже в случае ошибкиawaitmessage.answer("Ошибка обработки: {}".format(str(e)))importtracebacktraceback.print_exc()finally:if"temp_dir"inlocals():importshutilshutil.rmtree(temp_dir,ignore_errors=True)awaitmessage.answer("Выберите действие:",reply_markup=menu_buttons())awaitstate.set_state(Form.is_choosing)