Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -798,83 +798,37 @@ async def create_mask_sum(image: UploadFile = File(...), risk_level: int = Form(
|
|
798 |
@app.get("/", response_class=HTMLResponse)
|
799 |
async def read_root():
|
800 |
html_content = """
|
|
|
801 |
<!DOCTYPE html>
|
802 |
<html lang="ja">
|
803 |
<head>
|
804 |
<meta charset="UTF-8">
|
805 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
806 |
<title>画像処理アプリ</title>
|
807 |
-
<!-- Bootstrap CSS -->
|
808 |
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
809 |
-
<!-- jQuery UI CSS -->
|
810 |
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
811 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
|
812 |
<style>
|
813 |
-
body {
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
}
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
}
|
824 |
-
.
|
825 |
-
|
826 |
-
height: auto;
|
827 |
-
border-radius: 10px;
|
828 |
-
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
829 |
-
margin-top: 20px;
|
830 |
-
}
|
831 |
-
#result {
|
832 |
-
margin-top: 40px;
|
833 |
-
display: none;
|
834 |
-
}
|
835 |
-
.slider-container {
|
836 |
-
text-align: left;
|
837 |
-
margin-top: 20px;
|
838 |
-
}
|
839 |
-
.slider-label {
|
840 |
-
font-size: 1.2rem;
|
841 |
-
color: #333;
|
842 |
-
}
|
843 |
-
#slider {
|
844 |
-
margin-top: 10px;
|
845 |
-
}
|
846 |
-
.btn-primary {
|
847 |
-
background-color: #007bff;
|
848 |
-
border-color: #007bff;
|
849 |
-
font-size: 1.2rem;
|
850 |
-
padding: 10px 20px;
|
851 |
-
border-radius: 50px;
|
852 |
-
}
|
853 |
-
.btn-primary:hover {
|
854 |
-
background-color: #0056b3;
|
855 |
-
border-color: #004085;
|
856 |
-
}
|
857 |
-
.form-control, .custom-select {
|
858 |
-
border-radius: 20px;
|
859 |
-
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
860 |
-
}
|
861 |
-
.form-control-file {
|
862 |
-
font-size: 1rem;
|
863 |
-
}
|
864 |
-
.form-group {
|
865 |
-
margin-bottom: 25px;
|
866 |
-
}
|
867 |
-
.btn-success {
|
868 |
-
padding: 10px 20px;
|
869 |
-
border-radius: 50px;
|
870 |
-
}
|
871 |
</style>
|
872 |
</head>
|
873 |
<body>
|
874 |
<div class="container">
|
875 |
<h1><i class="fas fa-image"></i> 画像処理アプリ - モザイクとインペイント</h1>
|
876 |
<div class="form-group">
|
877 |
-
<input type="file" id="uploadImage" class="form-control-file" accept="image/*" onchange="
|
878 |
</div>
|
879 |
<img id="uploadedImage" class="image-preview" src="#" alt="アップロードされた画像" style="display: none;">
|
880 |
<div class="form-group mt-4">
|
@@ -897,14 +851,11 @@ async def read_root():
|
|
897 |
<a id="downloadLink" class="btn btn-success mt-3" href="#" download="processed_image.jpg">処理された画像をダウンロード</a>
|
898 |
</div>
|
899 |
</div>
|
900 |
-
<!-- jQuery and Bootstrap JS -->
|
901 |
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
902 |
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
903 |
-
<!-- jQuery UI -->
|
904 |
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
905 |
<script>
|
906 |
$(function() {
|
907 |
-
// スライダーの設定
|
908 |
$("#slider").slider({
|
909 |
range: "min",
|
910 |
value: 50,
|
@@ -916,22 +867,30 @@ async def read_root():
|
|
916 |
});
|
917 |
});
|
918 |
|
919 |
-
function
|
920 |
const fileInput = document.getElementById('uploadImage');
|
921 |
const uploadedImage = document.getElementById('uploadedImage');
|
922 |
if (fileInput.files && fileInput.files[0]) {
|
923 |
const reader = new FileReader();
|
924 |
-
reader.onload = function
|
925 |
const img = new Image();
|
926 |
img.onload = function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
927 |
const canvas = document.createElement('canvas');
|
|
|
|
|
928 |
const ctx = canvas.getContext('2d');
|
929 |
-
|
930 |
-
canvas.height = 480;
|
931 |
-
ctx.drawImage(img, 0, 0, 640, 480);
|
932 |
uploadedImage.src = canvas.toDataURL('image/jpeg');
|
933 |
uploadedImage.style.display = 'block';
|
934 |
-
uploadedImage.dataset.resizedImage = uploadedImage.src;
|
935 |
};
|
936 |
img.src = e.target.result;
|
937 |
};
|
@@ -940,63 +899,57 @@ async def read_root():
|
|
940 |
}
|
941 |
|
942 |
function processImage() {
|
|
|
943 |
const processingType = document.getElementById('processingType').value;
|
944 |
const riskLevel = $("#slider").slider("value");
|
945 |
const resultDiv = document.getElementById('result');
|
946 |
const processedImage = document.getElementById('processedImage');
|
947 |
const downloadLink = document.getElementById('downloadLink');
|
948 |
-
|
949 |
-
|
950 |
-
if (!resizedImageDataURL) {
|
951 |
alert("画像を選択してください。");
|
952 |
return;
|
953 |
}
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
})
|
990 |
-
.catch(error => {
|
991 |
-
console.error("画像処理に失敗しました。", error);
|
992 |
-
alert("画像処理に失敗しました。");
|
993 |
-
});
|
994 |
-
});
|
995 |
}
|
996 |
</script>
|
997 |
</body>
|
998 |
</html>
|
999 |
|
|
|
1000 |
"""
|
1001 |
return HTMLResponse(content=html_content)
|
1002 |
if __name__ == "__main__":
|
|
|
798 |
@app.get("/", response_class=HTMLResponse)
|
799 |
async def read_root():
|
800 |
html_content = """
|
801 |
+
|
802 |
<!DOCTYPE html>
|
803 |
<html lang="ja">
|
804 |
<head>
|
805 |
<meta charset="UTF-8">
|
806 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
807 |
<title>画像処理アプリ</title>
|
|
|
808 |
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
|
|
809 |
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
810 |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
|
811 |
<style>
|
812 |
+
body { background-color: #f0f0f5; color: #333; text-align: center; padding: 40px 20px; }
|
813 |
+
h1 { color: #555; margin-bottom: 30px; font-weight: bold; }
|
814 |
+
.image-preview, .processed-preview { max-width: 100%; height: auto; border-radius: 10px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); margin-top: 20px; }
|
815 |
+
#result { margin-top: 40px; display: none; }
|
816 |
+
.slider-container { text-align: left; margin-top: 20px; }
|
817 |
+
.slider-label { font-size: 1.2rem; color: #333; }
|
818 |
+
#slider { margin-top: 10px; }
|
819 |
+
.btn-primary { background-color: #007bff; border-color: #007bff; font-size: 1.2rem; padding: 10px 20px; border-radius: 50px; }
|
820 |
+
.btn-primary:hover { background-color: #0056b3; border-color: #004085; }
|
821 |
+
.form-control, .custom-select { border-radius: 20px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); }
|
822 |
+
.form-control-file { font-size: 1rem; }
|
823 |
+
.form-group { margin-bottom: 25px; }
|
824 |
+
.btn-success { padding: 10px 20px; border-radius: 50px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
825 |
</style>
|
826 |
</head>
|
827 |
<body>
|
828 |
<div class="container">
|
829 |
<h1><i class="fas fa-image"></i> 画像処理アプリ - モザイクとインペイント</h1>
|
830 |
<div class="form-group">
|
831 |
+
<input type="file" id="uploadImage" class="form-control-file" accept="image/*" onchange="previewAndResizeImage()">
|
832 |
</div>
|
833 |
<img id="uploadedImage" class="image-preview" src="#" alt="アップロードされた画像" style="display: none;">
|
834 |
<div class="form-group mt-4">
|
|
|
851 |
<a id="downloadLink" class="btn btn-success mt-3" href="#" download="processed_image.jpg">処理された画像をダウンロード</a>
|
852 |
</div>
|
853 |
</div>
|
|
|
854 |
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
855 |
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
|
|
856 |
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
857 |
<script>
|
858 |
$(function() {
|
|
|
859 |
$("#slider").slider({
|
860 |
range: "min",
|
861 |
value: 50,
|
|
|
867 |
});
|
868 |
});
|
869 |
|
870 |
+
function previewAndResizeImage() {
|
871 |
const fileInput = document.getElementById('uploadImage');
|
872 |
const uploadedImage = document.getElementById('uploadedImage');
|
873 |
if (fileInput.files && fileInput.files[0]) {
|
874 |
const reader = new FileReader();
|
875 |
+
reader.onload = function(e) {
|
876 |
const img = new Image();
|
877 |
img.onload = function() {
|
878 |
+
const maxWidth = 860;
|
879 |
+
const maxHeight = 860;
|
880 |
+
let width = img.width;
|
881 |
+
let height = img.height;
|
882 |
+
if (width > maxWidth || height > maxHeight) {
|
883 |
+
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
884 |
+
width = width * ratio;
|
885 |
+
height = height * ratio;
|
886 |
+
}
|
887 |
const canvas = document.createElement('canvas');
|
888 |
+
canvas.width = width;
|
889 |
+
canvas.height = height;
|
890 |
const ctx = canvas.getContext('2d');
|
891 |
+
ctx.drawImage(img, 0, 0, width, height);
|
|
|
|
|
892 |
uploadedImage.src = canvas.toDataURL('image/jpeg');
|
893 |
uploadedImage.style.display = 'block';
|
|
|
894 |
};
|
895 |
img.src = e.target.result;
|
896 |
};
|
|
|
899 |
}
|
900 |
|
901 |
function processImage() {
|
902 |
+
const fileInput = document.getElementById('uploadImage');
|
903 |
const processingType = document.getElementById('processingType').value;
|
904 |
const riskLevel = $("#slider").slider("value");
|
905 |
const resultDiv = document.getElementById('result');
|
906 |
const processedImage = document.getElementById('processedImage');
|
907 |
const downloadLink = document.getElementById('downloadLink');
|
908 |
+
if (fileInput.files.length === 0) {
|
|
|
|
|
909 |
alert("画像を選択してください。");
|
910 |
return;
|
911 |
}
|
912 |
+
const file = fileInput.files[0];
|
913 |
+
const formData = new FormData();
|
914 |
+
formData.append('image', file);
|
915 |
+
formData.append('risk_level', riskLevel);
|
916 |
+
let apiEndpoint;
|
917 |
+
if (processingType === "opencv") {
|
918 |
+
apiEndpoint = "/create-mask-and-inpaint-opencv";
|
919 |
+
} else if (processingType === "simple_lama") {
|
920 |
+
apiEndpoint = "/create-mask-and-inpaint-simple-lama";
|
921 |
+
} else if (processingType === "stamp") {
|
922 |
+
apiEndpoint = "/create-mask-and-inpaint-stamp";
|
923 |
+
} else if (processingType == "mosaic") {
|
924 |
+
apiEndpoint = "/create-mask-and-inpaint-mosaic";
|
925 |
+
}
|
926 |
+
const url = "https://rein0421-aidentify.hf.space" + apiEndpoint;
|
927 |
+
fetch(url, {
|
928 |
+
method: 'POST',
|
929 |
+
body: formData
|
930 |
+
})
|
931 |
+
.then(response => {
|
932 |
+
if (!response.ok) {
|
933 |
+
throw new Error("Network response was not ok");
|
934 |
+
}
|
935 |
+
return response.blob();
|
936 |
+
})
|
937 |
+
.then(blob => {
|
938 |
+
const objectURL = URL.createObjectURL(blob);
|
939 |
+
processedImage.src = objectURL;
|
940 |
+
downloadLink.href = objectURL;
|
941 |
+
resultDiv.style.display = "block";
|
942 |
+
})
|
943 |
+
.catch(error => {
|
944 |
+
console.error("画像処理に失敗しました。", error);
|
945 |
+
alert("画像処理に失敗しました。");
|
946 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
}
|
948 |
</script>
|
949 |
</body>
|
950 |
</html>
|
951 |
|
952 |
+
|
953 |
"""
|
954 |
return HTMLResponse(content=html_content)
|
955 |
if __name__ == "__main__":
|