| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 | 
							- // nativeplugins/opencv/android/uts/BitmapUtils.uts
 
- import Bitmap from 'android.graphics.Bitmap'
 
- import Base64 from 'android.util.Base64'
 
- import BitmapFactory from 'android.graphics.BitmapFactory'
 
- // 定义类型接口
 
- type ImageClarityScore = {
 
-     score: number
 
-     level: string
 
- }
 
- type ImageClarityResult = {
 
-     score: number
 
-     level: string
 
-     isClear: boolean
 
- }
 
- /**
 
-  * 图像清晰度检测工具类
 
-  */
 
- export class BitmapUtils {
 
-     
 
-     /**
 
-      * 计算图像的亮度方差作为清晰度指标
 
-      */
 
-     static calculateBrightnessVariance(bitmap: Bitmap): number {
 
-         try {
 
-             const width = bitmap.getWidth()
 
-             const height = bitmap.getHeight()
 
-             
 
-             // 根据原始尺寸动态计算采样尺寸
 
-             // 目标采样区域的总像素数,控制在合理范围内
 
-             const targetPixelCount = 2500 // 50x50 = 2500像素
 
-             
 
-             // 计算合适的采样尺寸,保持宽高比
 
-             let sampleWidth: number
 
-             let sampleHeight: number
 
-             
 
-             if (width > height) {
 
-                 // 宽图
 
-                 sampleWidth = Math.min(width, Math.sqrt(targetPixelCount * width / height).toInt())
 
-                 sampleHeight = Math.min(height, (sampleWidth * height / width).toInt())
 
-             } else {
 
-                 // 高图或方图
 
-                 sampleHeight = Math.min(height, Math.sqrt(targetPixelCount * height / width).toInt())
 
-                 sampleWidth = Math.min(width, (sampleHeight * width / height).toInt())
 
-             }
 
-             
 
-             // 确保最小尺寸
 
-             sampleWidth = Math.max(sampleWidth, 32)
 
-             sampleHeight = Math.max(sampleHeight, 32)
 
-             
 
-             const scaledBitmap = Bitmap.createScaledBitmap(
 
-                 bitmap, 
 
-                 sampleWidth.toInt(), 
 
-                 sampleHeight.toInt(), 
 
-                 false
 
-             )
 
-             
 
-             let totalBrightness = 0.0
 
-             let brightnessSquares = 0.0
 
-             const pixelCount = sampleWidth * sampleHeight
 
-             
 
-             // 计算平均亮度
 
-             for (let i: number = 0; i < sampleWidth; i++) {
 
-                 for (let j: number = 0; j < sampleHeight; j++) {
 
-                     const pixel = scaledBitmap.getPixel(i.toInt(), j.toInt())
 
-                     const brightness = this.getPixelBrightness(pixel)
 
-                     totalBrightness += brightness
 
-                 }
 
-             }
 
-             
 
-             const meanBrightness = totalBrightness / pixelCount
 
-             
 
-             // 计算亮度方差
 
-             for (let i: number = 0; i < sampleWidth; i++) {
 
-                 for (let j: number = 0; j < sampleHeight; j++) {
 
-                     const pixel = scaledBitmap.getPixel(i.toInt(), j.toInt())
 
-                     const brightness = this.getPixelBrightness(pixel)
 
-                     const diff = brightness - meanBrightness
 
-                     brightnessSquares += diff * diff
 
-                 }
 
-             }
 
-             
 
-             const variance = brightnessSquares / pixelCount
 
-             
 
-             // 回收临时Bitmap
 
-             if (!scaledBitmap.isRecycled()) {
 
-                 scaledBitmap.recycle()
 
-             }
 
-             
 
-             return variance
 
-             
 
-         } catch (error) {
 
-             console.error('清晰度计算失败:', error)
 
-             return -1
 
-         }
 
-     }
 
- 	
 
- 	// 在calculateBrightnessVariance方法中使用多尺度采样
 
- 	static calculateBrightnessVariance2(bitmap: Bitmap): number {
 
- 	    try {
 
- 	        const width = bitmap.getWidth()
 
- 	        const height = bitmap.getHeight()
 
- 	        
 
- 	        // 对2048×1536的图片,使用多个采样尺度
 
- 	        const scales = [
 
- 	            { width: 200, height: 150 },   // 约10%尺度
 
- 	            { width: 100, height: 75 },    // 约5%尺度  
 
- 	            { width: 50, height: 38 }      // 约2.5%尺度
 
- 	        ]
 
- 	        
 
- 	        let totalVariance = 0.0
 
- 	        let scaleCount = 0
 
- 	        
 
- 	        for (const scale of scales) {
 
- 	            const sampleWidth = Math.min(width, scale.width as number)
 
- 	            const sampleHeight = Math.min(height, scale.height as number)
 
- 	            
 
- 	            if (sampleWidth < 32 || sampleHeight < 32) continue
 
- 	            
 
- 	            const scaledBitmap = Bitmap.createScaledBitmap(
 
- 	                bitmap, 
 
- 	                sampleWidth.toInt(), 
 
- 	                sampleHeight.toInt(), 
 
- 	                false
 
- 	            )
 
- 	            
 
- 	            const variance = this.calculateVarianceForBitmap(scaledBitmap)
 
- 	            totalVariance += variance
 
- 	            scaleCount++
 
- 	            
 
- 	            if (!scaledBitmap.isRecycled()) {
 
- 	                scaledBitmap.recycle()
 
- 	            }
 
- 	        }
 
- 	        
 
- 	        return scaleCount > 0 ? totalVariance / scaleCount : -1
 
- 	        
 
- 	    } catch (error) {
 
- 	        console.error('多尺度清晰度计算失败:', error)
 
- 	        return -1
 
- 	    }
 
- 	}
 
- 	
 
- 	// 提取方差计算为独立方法
 
- 	private static calculateVarianceForBitmap(bitmap: Bitmap): number {
 
- 	    const width = bitmap.getWidth()
 
- 	    const height = bitmap.getHeight()
 
- 	    
 
- 	    let totalBrightness = 0.0
 
- 	    let brightnessSquares = 0.0
 
- 	    const pixelCount = width * height
 
- 	    
 
- 	    // 计算平均亮度
 
- 	    for (let i: number = 0; i < width; i++) {
 
- 	        for (let j: number = 0; j < height; j++) {
 
- 	            const pixel = bitmap.getPixel(i.toInt(), j.toInt())
 
- 	            const brightness = this.getPixelBrightness(pixel)
 
- 	            totalBrightness += brightness
 
- 	        }
 
- 	    }
 
- 	    
 
- 	    const meanBrightness = totalBrightness / pixelCount
 
- 	    
 
- 	    // 计算亮度方差
 
- 	    for (let i: number = 0; i < width; i++) {
 
- 	        for (let j: number = 0; j < height; j++) {
 
- 	            const pixel = bitmap.getPixel(i.toInt(), j.toInt())
 
- 	            const brightness = this.getPixelBrightness(pixel)
 
- 	            const diff = brightness - meanBrightness
 
- 	            brightnessSquares += diff * diff
 
- 	        }
 
- 	    }
 
- 	    
 
- 	    return brightnessSquares / pixelCount
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 使用边缘密度作为清晰度指标(更适合大图)
 
- 	 */
 
- 	static calculateEdgeDensity(bitmap: Bitmap): number {
 
- 	    try {
 
- 	        const width = bitmap.getWidth()
 
- 	        const height = bitmap.getHeight()
 
- 	        
 
- 	        // 对于大图,使用适当的采样尺寸
 
- 	        const sampleWidth = Math.min(width, 300)
 
- 	        const sampleHeight = Math.min(height, (300 * height / width).toInt())
 
- 	        
 
- 	        const scaledBitmap = Bitmap.createScaledBitmap(
 
- 	            bitmap, 
 
- 	            sampleWidth.toInt(), 
 
- 	            sampleHeight.toInt(), 
 
- 	            false
 
- 	        )
 
- 	        
 
- 	        let edgeCount = 0
 
- 	        const totalPixels = sampleWidth * sampleHeight
 
- 	        
 
- 	        // 简单的边缘检测
 
- 	        for (let i: number = 1; i < sampleWidth - 1; i++) {
 
- 	            for (let j: number = 1; j < sampleHeight - 1; j++) {
 
- 	                const center = this.getPixelBrightness(scaledBitmap.getPixel(i.toInt(), j.toInt()))
 
- 	                const right = this.getPixelBrightness(scaledBitmap.getPixel((i + 1).toInt(), j.toInt()))
 
- 	                const bottom = this.getPixelBrightness(scaledBitmap.getPixel(i.toInt(), (j + 1).toInt()))
 
- 	                
 
- 	                // 如果相邻像素亮度差异大,认为是边缘
 
- 	                if (Math.abs(center - right) > 20 || Math.abs(center - bottom) > 20) {
 
- 	                    edgeCount++
 
- 	                }
 
- 	            }
 
- 	        }
 
- 	        
 
- 	        const edgeDensity = (edgeCount / totalPixels) * 1000
 
- 	        
 
- 	        if (!scaledBitmap.isRecycled()) {
 
- 	            scaledBitmap.recycle()
 
- 	        }
 
- 	        
 
- 	        return edgeDensity
 
- 	        
 
- 	    } catch (error) {
 
- 	        console.error('边缘密度计算失败:', error)
 
- 	        return -1
 
- 	    }
 
- 	}
 
-     
 
-     /**
 
-      * 获取像素亮度
 
-      */
 
-     private static getPixelBrightness(pixel: number): number {
 
-         const r = (pixel >> 16) & 0xff
 
-         const g = (pixel >> 8) & 0xff
 
-         const b = pixel & 0xff
 
-         return (r + g + b) / 3.0
 
-     }
 
-     
 
-     /**
 
-      * 判断图像是否清晰
 
-      */
 
-     static isImageClear(bitmap: Bitmap, threshold: number = 500): boolean {
 
-         const variance = this.calculateBrightnessVariance2(bitmap)
 
-         return variance > threshold
 
-     }
 
-     
 
-     /**
 
-      * 获取图像清晰度评分
 
-      */
 
-     static getImageClarityScore(bitmap: Bitmap): ImageClarityScore {
 
-         const variance = this.calculateBrightnessVariance2(bitmap)
 
-         
 
-         let level: string
 
-         if (variance < 0) {
 
-             level = "处理失败"
 
-         } else if (variance < 500) {
 
-             level = "非常模糊"
 
-         } else if (variance < 2000) {
 
-             level = "模糊"
 
-         } else if (variance < 3200) {
 
-             level = "一般"
 
-         } else if (variance < 3500) {
 
-             level = "清晰"
 
-         } else {
 
-             level = "非常清晰"
 
-         }
 
-         
 
-         return {
 
-             score: Math.round(variance * 100) / 100,
 
-             level: level
 
-         }
 
-     }
 
-     
 
-     /**
 
-      * 从Base64数据检测清晰度
 
-      */
 
-     static checkImageClarityFromBase64(base64Data: string): ImageClarityResult {
 
-         try {
 
-             const bitmap = this.base64ToBitmap(base64Data)
 
-             if (bitmap == null) {
 
-                 return { score: -1, level: "加载失败", isClear: false }
 
-             }
 
-             
 
-             const clarityInfo = this.getImageClarityScore(bitmap)
 
-             const isClear = this.isImageClear(bitmap)
 
-             
 
-             if (!bitmap.isRecycled()) {
 
-                 bitmap.recycle()
 
-             }
 
-             
 
-             return {
 
-                 score: clarityInfo.score,
 
-                 level: clarityInfo.level,
 
-                 isClear: isClear
 
-             }
 
-             
 
-         } catch (error) {
 
-             console.error('图像清晰度检测失败:', error)
 
-             return { score: -1, level: "检测失败", isClear: false }
 
-         }
 
-     }
 
-     
 
-     /**
 
-      * 从文件路径检测清晰度
 
-      */
 
-     static checkImageClarityFromPath(imagePath: string): ImageClarityResult {
 
-         try {
 
-             const bitmap = BitmapFactory.decodeFile(imagePath)
 
-             if (bitmap == null) {
 
-                 return { score: -1, level: "加载失败", isClear: false }
 
-             }
 
-             
 
-             const clarityInfo = this.getImageClarityScore(bitmap)
 
-             const isClear = this.isImageClear(bitmap)
 
-             
 
-             if (!bitmap.isRecycled()) {
 
-                 bitmap.recycle()
 
-             }
 
-             
 
-             return {
 
-                 score: clarityInfo.score,
 
-                 level: clarityInfo.level,
 
-                 isClear: isClear
 
-             }
 
-             
 
-         } catch (error) {
 
-             console.error('图像清晰度检测失败:', error)
 
-             return { score: -1, level: "检测失败", isClear: false }
 
-         }
 
-     }
 
-     
 
-     /**
 
-      * 简化的Base64转Bitmap方法
 
-      */
 
-     private static base64ToBitmap(base64Data: string): Bitmap | null {
 
-         try {
 
-             // 移除Base64前缀
 
-             let pureBase64 = base64Data
 
-             if (base64Data.includes(',')) {
 
-                 pureBase64 = base64Data.split(',')[1]
 
-             }
 
-             
 
-             // 解码Base64
 
-             const decodedBytes = Base64.decode(pureBase64, Base64.DEFAULT)
 
-             
 
-             // 获取字节数组长度
 
-             const bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
 
-             
 
-             return bitmap
 
-             
 
-         } catch (error) {
 
-             console.error('Base64转Bitmap失败:', error)
 
-             return null
 
-         }
 
-     }
 
-     
 
-     /**
 
-      * 备用方法:直接返回清晰度分数(避免复杂对象类型)
 
-      */
 
-     static getSimpleClarityScore(bitmap: Bitmap): number {
 
-         return this.calculateBrightnessVariance(bitmap)
 
-     }
 
-     
 
-     /**
 
-      * 从Base64获取简单清晰度分数
 
-      */
 
-     static getSimpleClarityScoreFromBase64(base64Data: string): number {
 
-         try {
 
-             const bitmap = this.base64ToBitmap(base64Data)
 
-             if (bitmap == null) {
 
-                 return -1
 
-             }
 
-             
 
-             const score = this.calculateBrightnessVariance(bitmap)
 
-             
 
-             if (!bitmap.isRecycled()) {
 
-                 bitmap.recycle()
 
-             }
 
-             
 
-             return score
 
-             
 
-         } catch (error) {
 
-             console.error('清晰度检测失败:', error)
 
-             return -1
 
-         }
 
-     }
 
- }
 
 
  |