diff --git a/MiniScanner.xcodeproj/project.pbxproj b/MiniScanner.xcodeproj/project.pbxproj
index 53b844d0751001e57d0bac1a8faca81657103da0..25ca052a30d28186ba5ac42d5d81bdd87c90806f 100644
--- a/MiniScanner.xcodeproj/project.pbxproj
+++ b/MiniScanner.xcodeproj/project.pbxproj
@@ -238,6 +238,8 @@
 		678BD7172C4CF1EB00833DA5 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678BD7122C4CF1EB00833DA5 /* SettingsViewModel.swift */; };
 		678BD71D2C4D057200833DA5 /* UIImage+Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678BD71C2C4D057200833DA5 /* UIImage+Images.swift */; };
 		678BD71F2C4D07B100833DA5 /* Image+Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678BD71E2C4D07B100833DA5 /* Image+Images.swift */; };
+		6794328C2C689E9F002E5F8D /* WXCompress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6794328B2C689E9F002E5F8D /* WXCompress.swift */; };
+		6794328F2C68A991002E5F8D /* mozjpeg in Frameworks */ = {isa = PBXBuildFile; productRef = 6794328E2C68A991002E5F8D /* mozjpeg */; };
 		67959CC42C566B7A00CAB102 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67959CC32C566B7A00CAB102 /* Icons.xcassets */; };
 		67A20DDD2C57A142009D2F25 /* DocumentLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A20DDC2C57A142009D2F25 /* DocumentLayout.swift */; };
 		67A20DE12C57BC56009D2F25 /* DocumentsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A20DDF2C57BC56009D2F25 /* DocumentsCollectionViewCell.swift */; };
@@ -245,6 +247,7 @@
 		67A20DE42C57BC89009D2F25 /* DocumentsCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A20DE32C57BC89009D2F25 /* DocumentsCellDelegate.swift */; };
 		67D714B52C5161A30065E6F4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67D714B42C5161A30065E6F4 /* Images.xcassets */; };
 		67E6A1962C64DEB400A77F29 /* ScannedItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6A1952C64DEB400A77F29 /* ScannedItemType.swift */; };
+		67E6A1982C65151F00A77F29 /* ImageCompressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6A1972C65151F00A77F29 /* ImageCompressView.swift */; };
 		B827E5196CC419E773B843E1 /* Pods_MiniScanner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9A37DC9F9A8E3AF632DFB98 /* Pods_MiniScanner.framework */; };
 		EC0CF1FE254D8BBF00888722 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0CF1FD254D8BBF00888722 /* AppDelegate.swift */; };
 		EC0CF200254D8BBF00888722 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0CF1FF254D8BBF00888722 /* SceneDelegate.swift */; };
@@ -529,6 +532,7 @@
 		678BD7122C4CF1EB00833DA5 /* SettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
 		678BD71C2C4D057200833DA5 /* UIImage+Images.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Images.swift"; sourceTree = "<group>"; };
 		678BD71E2C4D07B100833DA5 /* Image+Images.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image+Images.swift"; sourceTree = "<group>"; };
+		6794328B2C689E9F002E5F8D /* WXCompress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WXCompress.swift; sourceTree = "<group>"; };
 		67959CC32C566B7A00CAB102 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = "<group>"; };
 		67A20DDC2C57A142009D2F25 /* DocumentLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentLayout.swift; sourceTree = "<group>"; };
 		67A20DDF2C57BC56009D2F25 /* DocumentsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsCollectionViewCell.swift; sourceTree = "<group>"; };
@@ -536,6 +540,7 @@
 		67A20DE32C57BC89009D2F25 /* DocumentsCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsCellDelegate.swift; sourceTree = "<group>"; };
 		67D714B42C5161A30065E6F4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
 		67E6A1952C64DEB400A77F29 /* ScannedItemType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannedItemType.swift; sourceTree = "<group>"; };
+		67E6A1972C65151F00A77F29 /* ImageCompressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCompressView.swift; sourceTree = "<group>"; };
 		E8AF4FB39674DF589D719DCF /* Pods-MiniScanner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MiniScanner.release.xcconfig"; path = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig"; sourceTree = "<group>"; };
 		E9A37DC9F9A8E3AF632DFB98 /* Pods_MiniScanner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MiniScanner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		EC0CF1FA254D8BBF00888722 /* MiniScanner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MiniScanner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -583,6 +588,7 @@
 				539D1C972C171344009DB24A /* LNExtensionExecutor in Frameworks */,
 				539996542C2711BA00671340 /* ZLImageEditor in Frameworks */,
 				53A4788A2C358FFA0073E956 /* ImageViewer_swift in Frameworks */,
+				6794328F2C68A991002E5F8D /* mozjpeg in Frameworks */,
 				53A478812C358E100073E956 /* LanguageManager-iOS in Frameworks */,
 				B827E5196CC419E773B843E1 /* Pods_MiniScanner.framework in Frameworks */,
 			);
@@ -1395,6 +1401,15 @@
 			path = Settings;
 			sourceTree = "<group>";
 		};
+		6794328A2C689E78002E5F8D /* Compress */ = {
+			isa = PBXGroup;
+			children = (
+				67E6A1972C65151F00A77F29 /* ImageCompressView.swift */,
+				6794328B2C689E9F002E5F8D /* WXCompress.swift */,
+			);
+			path = Compress;
+			sourceTree = "<group>";
+		};
 		67A20DDE2C57BC32009D2F25 /* DocumentsCollectionViewCell */ = {
 			isa = PBXGroup;
 			children = (
@@ -1541,6 +1556,7 @@
 		EC8A9B2C254DE94900F9AF99 /* DocumentPreview */ = {
 			isa = PBXGroup;
 			children = (
+				6794328A2C689E78002E5F8D /* Compress */,
 				ECA1FAA0254DEA6A0081F00B /* DocumentPreview.storyboard */,
 				EC8A9B26254DE91B00F9AF99 /* DocumentPreviewViewController.swift */,
 				EC702521254DF13200BE1958 /* PencilKitViewController.swift */,
@@ -1597,6 +1613,7 @@
 				53A478862C358F4A0073E956 /* Toast */,
 				53A478892C358FFA0073E956 /* ImageViewer_swift */,
 				6708A6032C50FCA50036805D /* EPSignature */,
+				6794328E2C68A991002E5F8D /* mozjpeg */,
 			);
 			productName = MiniScanner;
 			productReference = EC0CF1FA254D8BBF00888722 /* MiniScanner.app */;
@@ -1636,6 +1653,7 @@
 				53A478852C358F4A0073E956 /* XCRemoteSwiftPackageReference "Toast-Swift" */,
 				53A478882C358FFA0073E956 /* XCRemoteSwiftPackageReference "ImageViewer" */,
 				6708A6022C50FCA50036805D /* XCRemoteSwiftPackageReference "BeInEPSignature" */,
+				6794328D2C68A991002E5F8D /* XCRemoteSwiftPackageReference "mozjpeg.swift" */,
 			);
 			productRefGroup = EC0CF1FB254D8BBF00888722 /* Products */;
 			projectDirPath = "";
@@ -1917,9 +1935,11 @@
 				53014F962C11A8E80071CE39 /* ScannerViewController.swift in Sources */,
 				53014FA52C11A8E80071CE39 /* EditScanCornerView.swift in Sources */,
 				677E65EE2C5A6C0A0039E2C5 /* SessionModel.xcdatamodeld in Sources */,
+				6794328C2C689E9F002E5F8D /* WXCompress.swift in Sources */,
 				53E7D3382C1B00880025A1D3 /* FSPagerViewLayoutAttributes.swift in Sources */,
 				53014F8E2C11A8E80071CE39 /* ImageScannerController.swift in Sources */,
 				677E65E92C5A36A40039E2C5 /* UpdateScanSessionUseCase.swift in Sources */,
+				67E6A1982C65151F00A77F29 /* ImageCompressView.swift in Sources */,
 				539996A42C27130000671340 /* ConstraintMakerRelatable.swift in Sources */,
 				677E65C92C5A1A7D0039E2C5 /* ScanMapper.swift in Sources */,
 				678BD7162C4CF1EB00833DA5 /* SettingsViewCoordinator.swift in Sources */,
@@ -2220,6 +2240,14 @@
 				kind = branch;
 			};
 		};
+		6794328D2C68A991002E5F8D /* XCRemoteSwiftPackageReference "mozjpeg.swift" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/awxkee/mozjpeg.swift.git";
+			requirement = {
+				kind = upToNextMajorVersion;
+				minimumVersion = 1.1.3;
+			};
+		};
 /* End XCRemoteSwiftPackageReference section */
 
 /* Begin XCSwiftPackageProductDependency section */
@@ -2258,6 +2286,11 @@
 			package = 6708A6022C50FCA50036805D /* XCRemoteSwiftPackageReference "BeInEPSignature" */;
 			productName = EPSignature;
 		};
+		6794328E2C68A991002E5F8D /* mozjpeg */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 6794328D2C68A991002E5F8D /* XCRemoteSwiftPackageReference "mozjpeg.swift" */;
+			productName = mozjpeg;
+		};
 /* End XCSwiftPackageProductDependency section */
 
 /* Begin XCVersionGroup section */
diff --git a/MiniScanner/Modules/DocumentPreview/Compress/ImageCompressView.swift b/MiniScanner/Modules/DocumentPreview/Compress/ImageCompressView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..7fdf858c30a73f51eb29c72144e24daad5e48e41
--- /dev/null
+++ b/MiniScanner/Modules/DocumentPreview/Compress/ImageCompressView.swift
@@ -0,0 +1,246 @@
+//
+//  ImageCompressView.swift
+//  MiniScanner
+//
+//  Created by Mustafa Merza on 8/8/24.
+//  Copyright © 2024 AppsNectar. All rights reserved.
+//
+
+import SwiftUI
+import mozjpeg
+
+struct ImageCompressView: View {
+    
+    var image: UIImage
+    
+    var columns = [GridItem(.flexible()), GridItem(.flexible())]
+    
+    @State private var images: [[UIImage]] = Array(repeating: Array(repeating: UIImage(), count: 4), count: 4)
+    
+    init(image: UIImage) {
+        self.image = image
+    }
+    
+    var body: some View {
+        ScrollView(showsIndicators: false) {
+            
+            VStack(spacing: 16) {
+                
+                imagesGrid("") {
+                    
+                    original
+                    
+                    uiImage1
+                    
+                    timeline1
+                    
+                    mozjpeg1
+                }
+                
+                imagesGrid("") {
+                    
+                    original
+                    
+                    uiImage2
+                    
+                    timeline2
+                    
+                    mozjpeg2
+                }
+                
+                imagesGrid("") {
+                    
+                    original
+                    
+                    uiImage3
+                    
+                    timeline3
+                    
+                    mozjpeg3
+                }
+                
+                imagesGrid("Dec") {
+                    
+                    original
+                    
+                    decMozjpeg1
+                    
+                    decMozjpeg2
+                    
+                    decMozjpeg3
+                }
+            }
+            .padding(.all, 8)
+        }
+        .task {
+            await prepareImages()
+        }
+    }
+    
+    private func prepareImages() async {
+        
+        images[0][0] = image
+        images[1][0] = image
+        images[2][0] = image
+        
+        images[0][1] = compressImages(image: image, compressionQuality: 1)
+        images[1][1] = compressImages(image: image, compressionQuality: 0.5)
+        images[2][1] = compressImages(image: image, compressionQuality: 0)
+        
+        images[0][2] = image.wxCompress()
+        images[1][2] = image.wxCompress().wxCompress()
+        images[2][2] = image.wxCompress().wxCompress().wxCompress()
+        
+        images[0][3] = compressImagesWithMozJpeg(image: image, quality: 1)
+        images[1][3] = compressImagesWithMozJpeg(image: image, quality: 0.5)
+        images[2][3] = compressImagesWithMozJpeg(image: image, quality: 0)
+        
+        images[3][0] = decompressImagesWithMozJpeg(image: image, quality: 1)
+        images[3][1] = decompressImagesWithMozJpeg(image: image, quality: 0.5)
+        images[3][2] = decompressImagesWithMozJpeg(image: image, quality: 0)
+    }
+    
+    private var original: some View {
+        imageView(image: image,
+                  title: "Original")
+    }
+    
+    private var uiImage1: some View {
+        imageView(image: images[0][1],
+                  title: "UI Q 1")
+    }
+    
+    private var uiImage2: some View {
+        imageView(image: images[1][1],
+                  title: "UI Q 0.5")
+    }
+    
+    private var uiImage3: some View {
+        imageView(image: images[2][1],
+                  title: "UI Q 0")
+    }
+    
+    private var timeline1: some View {
+        imageView(image: images[0][2],
+                  title: "Timeline x1")
+    }
+    
+    private var timeline2: some View {
+        imageView(image: images[1][2],
+                  title: "Timeline x2")
+    }
+    
+    private var timeline3: some View {
+        imageView(image: images[2][2],
+                  title: "Timeline x3")
+    }
+    
+    private var mozjpeg1: some View {
+        imageView(image: images[0][3],
+                  title: "Moz Q 1")
+    }
+    
+    private var mozjpeg2: some View {
+        imageView(image: images[1][3],
+                  title: "Moz Q 0.5")
+    }
+    
+    private var mozjpeg3: some View {
+        imageView(image: images[2][3],
+                  title: "Moz Q 0")
+    }
+    
+    private var decMozjpeg1: some View {
+        imageView(image: images[3][0],
+                  title: "DeMoz Q 1")
+    }
+    
+    private var decMozjpeg2: some View {
+        imageView(image: images[3][1],
+                  title: "DeMoz Q 0.5")
+    }
+    
+    private var decMozjpeg3: some View {
+        imageView(image: images[3][2],
+                  title: "DeMoz Q 0")
+    }
+}
+
+extension ImageCompressView {
+    
+    private func imagesGrid(_ title: String, @ViewBuilder content: () -> some View) -> some View {
+        VStack(spacing: 2) {
+            
+            Text(title)
+            
+            LazyVGrid(columns: columns, alignment: .center) {
+                content()
+            }
+            .frame(maxWidth: .infinity, maxHeight: .infinity)
+        }
+    }
+    
+    private func imageView(image: UIImage, title: String) -> some View {
+        VStack {
+            
+            Text(title)
+            
+            Text(size(image: image))
+            
+            Image(uiImage: image)
+                .resizable()
+                .aspectRatio(contentMode: .fit)
+        }
+    }
+    
+    private func size(image: UIImage) -> String {
+        
+        var size = ""
+        
+        if let sizeInByte = image.jpegData(compressionQuality: 1)?.count {
+            
+            let sizeInMByte = Double(sizeInByte) / 1024.0 / 1024.0
+            
+            size = String(format: "%.4f MB", sizeInMByte)
+        }
+        
+        return size
+    }
+}
+
+extension ImageCompressView {
+    
+    private func compressImages(image: UIImage, compressionQuality: CGFloat) -> UIImage {
+        
+        if let data = image.jpegData(compressionQuality: compressionQuality),
+           let newImage = UIImage(data: data) {
+            return newImage
+        }
+        
+        return image
+    }
+    
+    private func compressImagesWithMozJpeg(image: UIImage, quality: Float) -> UIImage {
+        
+        if let data = try? image.mozjpegRepresentation(quality: quality),
+           let newImage = UIImage(data: data) {
+            return newImage
+        }
+        
+        return image
+    }
+    
+    private func decompressImagesWithMozJpeg(image: UIImage, quality: Float) -> UIImage {
+        
+        if let data = try? image.mozjpegRepresentation(quality: quality),
+           let newImage = Mozjpeg().decompress(chunk: data) {
+            return newImage
+        }
+        
+        return image
+    }
+}
+
+#Preview {
+    ImageCompressView(image: .actions)
+}
diff --git a/MiniScanner/Modules/DocumentPreview/Compress/WXCompress.swift b/MiniScanner/Modules/DocumentPreview/Compress/WXCompress.swift
new file mode 100644
index 0000000000000000000000000000000000000000..c86252fca805b4e822831a1f644c53372361e2cd
--- /dev/null
+++ b/MiniScanner/Modules/DocumentPreview/Compress/WXCompress.swift
@@ -0,0 +1,97 @@
+//
+//  WXCompress.swift
+//  MiniScanner
+//
+//  Created by Mustafa Merza on 8/11/24.
+//  Copyright © 2024 AppsNectar. All rights reserved.
+//
+
+import Foundation
+
+public enum WechatCompressType {
+    case session
+    case timeline
+}
+
+public extension UIImage {
+    
+    /**
+     wechat image compress
+     
+     - parameter type: session image boundary is 800, timeline is 1280
+     
+     - returns: thumb image
+     */
+    func wxCompress(type: WechatCompressType = .timeline) -> UIImage {
+        let size = self.wxImageSize(type: type)
+        let reImage = resizedImage(size: size)
+        let data = reImage.jpegData(compressionQuality: 0.5)!
+        return UIImage.init(data: data)!
+    }
+    
+    /**
+     get wechat compress image size
+     
+     - parameter type: session  / timeline
+     
+     - returns: size
+     */
+    private func wxImageSize(type: WechatCompressType) -> CGSize {
+        var width = self.size.width
+        var height = self.size.height
+        
+        var boundary: CGFloat = 1280
+        
+        // width, height <= 1280, Size remains the same
+        guard width > boundary || height > boundary else {
+            return CGSize(width: width, height: height)
+        }
+        
+        // aspect ratio
+        let s = max(width, height) / min(width, height)
+        if s <= 2 {
+            // Set the larger value to the boundary, the smaller the value of the compression
+            let x = max(width, height) / boundary
+            if width > height {
+                width = boundary
+                height = height / x
+            } else {
+                height = boundary
+                width = width / x
+            }
+        } else {
+            // width, height > 1280
+            if min(width, height) >= boundary {
+                boundary = type == .session ? 800 : 1280
+                // Set the smaller value to the boundary, and the larger value is compressed
+                let x = min(width, height) / boundary
+                if width < height {
+                    width = boundary
+                    height = height / x
+                } else {
+                    height = boundary
+                    width = width / x
+                }
+            }
+        }
+        return CGSize(width: width, height: height)
+    }
+    
+    /**
+     Zoom the picture to the specified size
+     
+     - parameter newSize: image size
+     
+     - returns: new image
+     */
+    private func resizedImage(size: CGSize) -> UIImage {
+        let newRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
+        var newImage: UIImage!
+        UIGraphicsBeginImageContext(newRect.size)
+        newImage = UIImage(cgImage: self.cgImage!, scale: 1, orientation: self.imageOrientation)
+        newImage.draw(in: newRect)
+        newImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+        return newImage
+    }
+}