sanjay7178 commited on
Commit
e972367
1 Parent(s): 26c4ccc

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile.txt +17 -0
  2. app.py +254 -0
  3. requirements.txt +21 -0
Dockerfile.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+ RUN sudo apt-get update
12
+ RUN sudo apt-get install python3-pypdf2
13
+
14
+ COPY --chown=user . /app
15
+ EXPOSE 7860
16
+
17
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import numpy as np
4
+ from PIL import Image, ImageDraw
5
+ import ffmpeg
6
+ import gradio as gr
7
+ from tqdm import tqdm
8
+ import zstandard as zstd
9
+ import brotli
10
+ import torch
11
+ import torchvision.transforms as transforms
12
+ from torch.nn import functional as F
13
+ import cupy as cp
14
+ import io
15
+ import mimetypes
16
+ from pydub import AudioSegment
17
+ from PyPDF2 import PdfFileReader, PdfFileWriter
18
+ import docx
19
+ import openpyxl
20
+
21
+ class GPUAcceleratedCompressionToolkit:
22
+ def __init__(self):
23
+ self.supported_formats = {
24
+ 'image': ['.jpg', '.jpeg', '.png', '.bmp', '.tiff'],
25
+ 'video': ['.mp4', '.avi', '.mov', '.mkv'],
26
+ 'audio': ['.mp3', '.wav', '.ogg', '.flac'],
27
+ 'document': ['.txt', '.pdf', '.doc', '.docx'],
28
+ 'spreadsheet': ['.xlsx', '.xls', '.csv']
29
+ }
30
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
31
+
32
+ def detect_file_type(self, file_path):
33
+ mime_type, _ = mimetypes.guess_type(file_path)
34
+ if mime_type:
35
+ type_category = mime_type.split('/')[0]
36
+ if type_category in ['image', 'video', 'audio']:
37
+ return type_category
38
+ elif type_category == 'application':
39
+ if mime_type in ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']:
40
+ return 'document'
41
+ elif mime_type in ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']:
42
+ return 'spreadsheet'
43
+ return 'other'
44
+
45
+ def compress_image(self, input_path, output_path, compression_level, use_gpu=False, output_format='original'):
46
+ img = Image.open(input_path)
47
+ original_format = img.format if img.format else 'JPEG'
48
+
49
+ if output_format == 'original':
50
+ save_format = original_format
51
+ else:
52
+ save_format = output_format.upper()
53
+
54
+ quality = int(compression_level)
55
+
56
+ if use_gpu:
57
+ tensor = transforms.ToTensor()(img).unsqueeze(0).to(self.device)
58
+
59
+ compressed = F.interpolate(tensor, scale_factor=quality/100, mode='bilinear', align_corners=False)
60
+ compressed = F.interpolate(compressed, size=tensor.shape[2:], mode='bilinear', align_corners=False)
61
+
62
+ result = transforms.ToPILImage()(compressed.squeeze(0).cpu())
63
+ result.save(output_path, format=save_format, quality=quality)
64
+ else:
65
+ img.save(output_path, format=save_format, quality=quality)
66
+
67
+ def compress_video(self, input_path, output_path, compression_level, use_gpu=False, output_format=None):
68
+ if use_gpu:
69
+ vcodec = 'h264_nvenc'
70
+ else:
71
+ vcodec = 'libx264'
72
+
73
+ crf = int(100 - compression_level) # Invert the scale for CRF
74
+
75
+ if output_format is None:
76
+ output_format = os.path.splitext(input_path)[1][1:]
77
+
78
+ (
79
+ ffmpeg
80
+ .input(input_path)
81
+ .output(output_path, vcodec=vcodec, crf=str(crf), acodec='aac', **{'preset': 'slow'})
82
+ .overwrite_output()
83
+ .run(capture_stdout=True, capture_stderr=True)
84
+ )
85
+
86
+ def compress_audio(self, input_path, output_path, compression_level, output_format=None):
87
+ if output_format is None:
88
+ output_format = os.path.splitext(input_path)[1][1:]
89
+
90
+ bitrate = f"{int(compression_level * 3.2)}k" # Scale compression_level to bitrate
91
+
92
+ audio = AudioSegment.from_file(input_path)
93
+ audio.export(output_path, format=output_format, bitrate=bitrate)
94
+
95
+ def compress_document(self, input_path, output_path, compression_level, output_format=None):
96
+ if output_format is None:
97
+ output_format = os.path.splitext(input_path)[1][1:]
98
+
99
+ if output_format == 'pdf':
100
+ with open(input_path, 'rb') as file:
101
+ reader = PdfFileReader(file)
102
+ writer = PdfFileWriter()
103
+ for page in range(reader.getNumPages()):
104
+ page = reader.getPage(page)
105
+ page.compressContentStreams() # This is CPU intensive!
106
+ writer.addPage(page)
107
+ with open(output_path, 'wb') as output_file:
108
+ writer.write(output_file)
109
+ elif output_format in ['doc', 'docx']:
110
+ doc = docx.Document(input_path)
111
+ doc.save(output_path)
112
+ else:
113
+ # For other document types, use generic file compression
114
+ self.compress_file_gpu(input_path, output_path, compression_level)
115
+
116
+ def compress_spreadsheet(self, input_path, output_path, compression_level, output_format=None):
117
+ if output_format is None:
118
+ output_format = os.path.splitext(input_path)[1][1:]
119
+
120
+ wb = openpyxl.load_workbook(input_path)
121
+ wb.save(output_path)
122
+
123
+ def compress_file_gpu(self, input_path, output_path, compression_level):
124
+ level = int(compression_level / 10) # Scale compression_level to Zstandard level
125
+
126
+ with open(input_path, 'rb') as f_in:
127
+ data = f_in.read()
128
+
129
+ d_data = cp.asarray(bytearray(data))
130
+ cctx = zstd.ZstdCompressor(level=level)
131
+ d_compressed = cp.asarray(bytearray(cctx.compress(d_data.get())))
132
+ compressed = d_compressed.get().tobytes()
133
+
134
+ with open(output_path, 'wb') as f_out:
135
+ f_out.write(compressed)
136
+
137
+ def batch_compress_gpu(self, input_files, output_dir, use_gpu, output_format, compression_level):
138
+ if not os.path.exists(output_dir):
139
+ os.makedirs(output_dir)
140
+
141
+ results = []
142
+ for file in tqdm(input_files):
143
+ input_path = file.name
144
+ file_type = self.detect_file_type(input_path)
145
+
146
+ # Determine output format and path
147
+ if output_format == 'original':
148
+ _, ext = os.path.splitext(input_path)
149
+ output_path = os.path.join(output_dir, f"compressed_{os.path.basename(input_path)}")
150
+ else:
151
+ output_path = os.path.join(output_dir, f"compressed_{os.path.splitext(os.path.basename(input_path))[0]}.{output_format}")
152
+
153
+ if file_type == 'image':
154
+ self.compress_image(input_path, output_path, compression_level, use_gpu=use_gpu, output_format=output_format)
155
+ elif file_type == 'video':
156
+ self.compress_video(input_path, output_path, compression_level, use_gpu=use_gpu, output_format=output_format if output_format != 'original' else None)
157
+ elif file_type == 'audio':
158
+ self.compress_audio(input_path, output_path, compression_level, output_format=output_format if output_format != 'original' else None)
159
+ elif file_type == 'document':
160
+ self.compress_document(input_path, output_path, compression_level, output_format=output_format if output_format != 'original' else None)
161
+ elif file_type == 'spreadsheet':
162
+ self.compress_spreadsheet(input_path, output_path, compression_level, output_format=output_format if output_format != 'original' else None)
163
+ else:
164
+ self.compress_file_gpu(input_path, output_path, compression_level)
165
+
166
+ results.append(output_path)
167
+
168
+ return results
169
+
170
+ def real_time_preview_gpu(self, input_path, compression_level, use_gpu=False):
171
+ file_type = self.detect_file_type(input_path)
172
+
173
+ if file_type == 'image':
174
+ img = Image.open(input_path)
175
+ if use_gpu:
176
+ tensor = transforms.ToTensor()(img).unsqueeze(0).to(self.device)
177
+ tensor = F.interpolate(tensor, size=(300, 300), mode='bilinear', align_corners=False)
178
+ compressed = F.interpolate(tensor, scale_factor=compression_level/100, mode='bilinear', align_corners=False)
179
+ compressed = F.interpolate(compressed, size=tensor.shape[2:], mode='bilinear', align_corners=False)
180
+ result = transforms.ToPILImage()(compressed.squeeze(0).cpu())
181
+ else:
182
+ img = img.resize((300, 300))
183
+ buffer = io.BytesIO()
184
+ img.save(buffer, format='JPEG', quality=int(compression_level))
185
+ buffer.seek(0)
186
+ result = Image.open(buffer)
187
+ return result
188
+ elif file_type == 'video':
189
+ video = cv2.VideoCapture(input_path)
190
+ ret, frame = video.read()
191
+ if ret:
192
+ if use_gpu:
193
+ d_frame = cp.asarray(frame)
194
+ d_frame = cp.resize(d_frame, (300, 300))
195
+ _, d_buffer = cv2.imencode('.jpg', cp.asnumpy(d_frame), [cv2.IMWRITE_JPEG_QUALITY, int(compression_level)])
196
+ else:
197
+ frame = cv2.resize(frame, (300, 300))
198
+ _, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, int(compression_level)])
199
+ return Image.open(io.BytesIO(buffer.tobytes()))
200
+ elif file_type in ['audio', 'document', 'spreadsheet', 'other']:
201
+ placeholder = Image.new('RGB', (300, 300), color='lightgray')
202
+ draw = ImageDraw.Draw(placeholder)
203
+ draw.text((10, 150), f"{file_type.capitalize()} Preview\nNot Available", fill='black')
204
+ return placeholder
205
+
206
+ return None
207
+
208
+ def gradio_interface(toolkit):
209
+ def process_files(files, use_gpu, output_format, compression_level):
210
+ output_dir = "compressed_output"
211
+ return toolkit.batch_compress_gpu(files, output_dir, use_gpu, output_format, compression_level)
212
+
213
+ def update_preview(file, compression_level, use_gpu):
214
+ if file is None:
215
+ return None
216
+ return toolkit.real_time_preview_gpu(file.name, compression_level, use_gpu)
217
+
218
+ iface = gr.Interface(
219
+ fn=process_files,
220
+ inputs=[
221
+ gr.File(label="Input Files", file_count="multiple"),
222
+ gr.Checkbox(label="Use GPU Acceleration"),
223
+ gr.Dropdown(
224
+ choices=["original", "jpg", "png", "mp4", "mp3", "pdf", "docx", "xlsx"],
225
+ label="Output Format",
226
+ value="original"
227
+ ),
228
+ gr.Slider(1, 100, 50, step=1, label="Compression Level")
229
+ ],
230
+ outputs=gr.File(label="Compressed Files", file_count="multiple"),
231
+ title="GPU-Accelerated Compression Toolkit",
232
+ description="Drag and drop files for compression of images, videos, audio, documents, spreadsheets, and other files. File type is automatically detected.",
233
+ allow_flagging="never"
234
+ )
235
+
236
+ preview = gr.Interface(
237
+ fn=update_preview,
238
+ inputs=[
239
+ gr.File(label="Input File"),
240
+ gr.Slider(1, 100, 50, step=1, label="Compression Level"),
241
+ gr.Checkbox(label="Use GPU Acceleration")
242
+ ],
243
+ outputs=gr.Image(label="Preview"),
244
+ title="Real-time Compression Preview",
245
+ live=True,
246
+ allow_flagging="never"
247
+ )
248
+
249
+ return gr.TabbedInterface([iface, preview], ["Compress", "Preview"])
250
+
251
+ if __name__ == "__main__":
252
+ toolkit = GPUAcceleratedCompressionToolkit()
253
+ interface = gradio_interface(toolkit)
254
+ interface.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Automatically generated by https://github.com/damnever/pigar.
2
+
3
+ Brotli==1.1.0
4
+ cupy-cuda12x==13.3.0
5
+ ffmpeg==1.4
6
+ gradio==4.44.0
7
+ numpy==1.24.4
8
+ openpyxl==3.1.5
9
+ Pillow==9.4.0
10
+ pydub==0.25.1
11
+ python-docx==1.1.2
12
+ torch
13
+ torchvision
14
+ tqdm==4.66.5
15
+ zstandard==0.23.0
16
+ python-docx
17
+
18
+
19
+ opencv-contrib-python==4.10.0.84
20
+ opencv-python==4.10.0.84
21
+ #opencv-python-headless==4.10.0.84