Repository: ultralytics/ultralytics
Issue category: Bug Report

Save_crop method from Results with default params results in double file extension
### Search before asking

- [X] I have searched the Ultralytics YOLO [issues](https://github.com/ultralytics/ultralytics/issues) and found no similar bug report.


### Ultralytics YOLO Component

Predict

### Bug

Save_crop method in the Results object already adds file extension to the saved image (.jpg) and default value is set as 'im.jpg' so when using default behaviour we get a file named **"im.jpg.jpg"**
With this few examples
`results[0].save_crop(save_dir='../out')`
`results[0].save_crop(save_dir='../out', file_name='img.png')`
`results[0].save_crop(save_dir='../out', file_name='img')`
Here are the outputs in a File Explorer, only one without double extension is when you add file_name without any extension
![image](https://github.com/user-attachments/assets/873bb127-ca4e-439d-8f74-8aece55fd3fa)


### Environment

Setup complete ✅ (8 CPUs, 15.9 GB RAM, 477.1/931.5 GB disk) 

OS                  Windows-10-10.0.17763-SP0
Environment         Windows
Python              3.10.15
Install             pip
RAM                 15.94 GB
Disk                477.1/931.5 GB
CPU                 Intel Core(TM) i7-9700 3.00GHz
CPU count           8
GPU                 NVIDIA GeForce GTX 1660, 6144MiB
GPU count           1
CUDA                11.8

numpy               ✅ 1.26.3>=1.23.0                                                                                                                                                                                               
matplotlib          ✅ 3.9.2>=3.3.0 
opencv-python       ✅ 4.10.0.84>=4.6.0                                                                                                                                                                                             
pillow              ✅ 10.2.0>=7.1.2                                                                                                                                                                                                
pyyaml              ✅ 6.0.2>=5.3.1                                                                                                                                                                                                 
requests            ✅ 2.32.3>=2.23.0                                                                                                                                                                                               
scipy               ✅ 1.14.1>=1.4.1 
torch               ✅ 2.5.1+cu118>=1.8.0                                                                                                                                                                                           
torchvision         ✅ 0.20.1+cu118>=0.9.0                                                                                                                                                                                          
tqdm                ✅ 4.67.0>=4.64.0                                                                                                                                                                                               
psutil              ✅ 6.1.0                                                                                                                                                                                                        
py-cpuinfo          ✅ 9.0.0                                                                                                                                                                                                        
pandas              ✅ 2.2.3>=1.1.4                                                                                                                                                                                                 
seaborn             ✅ 0.13.2>=0.11.0                                                                                                                                                                                               
ultralytics-thop    ✅ 2.0.11>=2.0.0                                                                                                                                                                                                
numpy               ✅ 1.26.3<2.0.0; sys_platform == "darwin"                                                                                                                                                                       
torch               ✅ 2.5.1+cu118!=2.4.0,>=1.8.0; sys_platform == "win32"   

### Minimal Reproducible Example

```
model = YOLO('../model/yolov8s.pt')
results = model.predict(frame, conf=0.5)
results[0].save_crop(save_dir='../out')
```

### Additional

_No response_

### Are you willing to submit a PR?

- [X] Yes I'd like to help by submitting a PR!


Functions to edit:
ultralytics/engine/results.py:Results.save_crop

Patch:
diff --git a/ultralytics/engine/results.py b/ultralytics/engine/results.py
index 029e4471e04..8de0a2e6a1c 100644
--- a/ultralytics/engine/results.py
+++ b/ultralytics/engine/results.py
@@ -750,7 +750,7 @@ def save_crop(self, save_dir, file_name=Path("im.jpg")):
             save_one_box(
                 d.xyxy,
                 self.orig_img.copy(),
-                file=Path(save_dir) / self.names[int(d.cls)] / f"{Path(file_name)}.jpg",
+                file=Path(save_dir) / self.names[int(d.cls)] / Path(file_name).with_suffix(".jpg"),
                 BGR=True,
             )