diff --git a/MisplaceAI/process_misplaced_manager/urls.py b/MisplaceAI/process_misplaced_manager/urls.py
index 7c43f0498adba3e8f0ccd791d19d4f6e3e71bf4d..e5fbda822f847faae7b1f5162b49f6c16cac6619 100644
--- a/MisplaceAI/process_misplaced_manager/urls.py
+++ b/MisplaceAI/process_misplaced_manager/urls.py
@@ -4,7 +4,7 @@ from rest_framework.routers import DefaultRouter
 from .views import (
     UploadedImageViewSet, UploadedVideoViewSet,
     normal_detection, 
-    display_results, display_video_results,upload_video
+    display_results, display_video_results,upload_video, download_image
 )
 
 router = DefaultRouter()
@@ -20,4 +20,7 @@ urlpatterns = [
     path('upload-video/', upload_video, name='upload_video'),
     path('video-results/<int:video_id>/', display_video_results, name='display_video_results'),
     path('display-results/<int:image_id>/', display_results, name='display_results'),
+    path('download/<path:file_path>/', download_image, name='download_image'),
+
+
 ]
diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py
index aaf6954dd6a211af6232c708d5ae8c8a2b0617b3..6ed5b0b866c3892171be57b7a6f7536cf02bf97b 100644
--- a/MisplaceAI/process_misplaced_manager/views.py
+++ b/MisplaceAI/process_misplaced_manager/views.py
@@ -17,7 +17,7 @@ from PIL import Image, ExifTags
 import logging
 import cv2
 from django.conf import settings
-from django.http import JsonResponse
+from django.http import JsonResponse,  HttpResponse, Http404
 import numpy as np  
 from moviepy.editor import VideoFileClip, ImageSequenceClip
 
@@ -245,21 +245,16 @@ def process_video_for_misplaced_objects(video_path, frame_interval):
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 
\ No newline at end of file
+#################################################################################################
+####################################### Download Results ########################################
+@api_view(['GET'])
+@permission_classes([IsAuthenticated])
+def download_image(request, file_path):
+    file_path = os.path.join(settings.MEDIA_ROOT, file_path)
+    if os.path.exists(file_path):
+        with open(file_path, 'rb') as f:
+            response = HttpResponse(f.read(), content_type="application/force-download")
+            response['Content-Disposition'] = f'attachment; filename="{os.path.basename(file_path)}"'
+            return response
+    else:
+        raise Http404
\ No newline at end of file
diff --git a/frontend/src/pages/NormalDetection/NormalDetectionPage.js b/frontend/src/pages/NormalDetection/NormalDetectionPage.js
index bf9472cc9946e8bfe7978bdc5079771a0a221a34..d4e0b0d66c10d9ad97ad09e97ebc05553f138d2e 100644
--- a/frontend/src/pages/NormalDetection/NormalDetectionPage.js
+++ b/frontend/src/pages/NormalDetection/NormalDetectionPage.js
@@ -1,7 +1,7 @@
 // src/pages/NormalDetection/NormalDetectionPage.js
 import React, { useState } from 'react';
 import { Modal, Button } from 'react-bootstrap';
-import { normalDetection } from '../../services/processMisplacedManagerApi';
+import { normalDetection, downloadImage } from '../../services/processMisplacedManagerApi';
 import '../../styles/main.css';
 import LoadingIndicator from '../../components/detection/LoadingIndicator';
 import DetectionResults from '../../components/detection/DetectionResults';
@@ -65,6 +65,22 @@ const NormalDetectionPage = () => {
         setDetectionComplete(false);
     };
 
+    const handleDownload = async () => {
+        try {
+            const filePath = resultImageUrl.split('/').pop(); // Get the file name only
+            const response = await downloadImage(filePath);
+            const url = window.URL.createObjectURL(new Blob([response.data]));
+            const link = document.createElement('a');
+            link.href = url;
+            link.setAttribute('download', `detection_result${resultImageUrl.substring(resultImageUrl.lastIndexOf('.'))}`);
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+        } catch (error) {
+            console.error('Error downloading image:', error);
+        }
+    };
+
     return (
         <DetectionContainer title="Upload Image for Normal Detection">
             <LoadingIndicator isLoading={isLoading} message="Your photo is being processed, please wait..." />
@@ -81,6 +97,9 @@ const NormalDetectionPage = () => {
                 <>
                     <DetectionResults result={{ output_image_url: resultImageUrl, misplaced_objects: misplacedObjects }} />
                     <div className="text-center mt-4">
+                        <Button onClick={handleDownload} className="btn btn-success mr-2">
+                            Download Image
+                        </Button>
                         <Button onClick={handleReset} className="btn btn-primary">
                             Detect Another Image
                         </Button>
diff --git a/frontend/src/services/processMisplacedManagerApi.js b/frontend/src/services/processMisplacedManagerApi.js
index 706674c467397fd735043a10dfe1b35b4a82d9d8..0cc683efa49ff7d51cd239a7742f27830ed05421 100644
--- a/frontend/src/services/processMisplacedManagerApi.js
+++ b/frontend/src/services/processMisplacedManagerApi.js
@@ -119,4 +119,18 @@ export const getVideoResults = async (id) => {
         console.error(`Error fetching video results with ID ${id}:`, error);
         throw error;
     }
+};
+
+
+// Function to download an image
+export const downloadImage = async (filePath) => {
+    try {
+        const response = await api.get(`/api/process_misplaced_manager/download/${filePath}/`, {
+            responseType: 'blob', // Important for handling file downloads
+        });
+        return response;
+    } catch (error) {
+        console.error('Error downloading image:', error);
+        throw error;
+    }
 };
\ No newline at end of file