smithery/raydocs

photo-standardization

标准化拍?

Installation

$ npx skills add smithery/raydocs --skill photo-standardization

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/raydocs · top by installs.

npx skills add smithery/raydocs

Browse all from smithery/raydocs

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,901 B
  • docs SUMMARY.md 164 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

标准化拍照技能

概述

确保每次拍照条件一致,使前后对比有效可信。

检测模块

1. 光线检测

class LightingDetector {
    func detectLighting(from sampleBuffer: CMSampleBuffer) -> LightingCondition {
        // 使用AVCaptureDevice获取曝光信息
        let exposureValue = calculateEV(from: sampleBuffer)
        
        switch exposureValue {
        case ..<6:
            return .tooDark(suggestion: "请移到光线更充足的地方")
        case 6..<8:
            return .slightlyDark(suggestion: "光线略暗,建议开灯或靠近窗户")
        case 8..<12:
            return .optimal
        case 12..<14:
            return .slightlyBright(suggestion: "光线略强,避免直射光")
        default:
            return .tooBright(suggestion: "光线过强,请避开强光源")
        }
    }
}

enum LightingCondition {
    case tooDark(suggestion: String)
    case slightlyDark(suggestion: String)
    case optimal
    case slightlyBright(suggestion: String)
    case tooBright(suggestion: String)
    
    var isAcceptable: Bool {
        switch self {
        case .optimal, .slightlyDark, .slightlyBright:
            return true
        default:
            return false
        }
    }
}

2. 角度检测

import Vision

class FaceAngleDetector {
    func detectFaceAngle(in image: CGImage) async throws -> FaceAngle {
        let request = VNDetectFaceRectanglesRequest()
        request.revision = VNDetectFaceRectanglesRequestRevision3
        
        let handler = VNImageRequestHandler(cgImage: image)
        try handler.perform([request])
        
        guard let face = request.results?.first else {
            throw DetectionError.noFaceDetected
        }
        
        return FaceAngle(
            yaw: face.yaw?.doubleValue ?? 0,    // 左右转头
            pitch: face.pitch?.doubleValue ?? 0, // 上下点头
            roll: face.roll?.doubleValue ?? 0    // 歪头
        )
    }
}

struct FaceAngle {
    let yaw: Double
    let pitch: Double
    let roll: Double
    
    var isOptimal: Bool {
        abs(yaw) < 10 && abs(pitch) < 10 && abs(roll) < 5
    }
    
    var suggestion: String? {
        if abs(yaw) >= 10 {
            return yaw > 0 ? "请稍微向左转" : "请稍微向右转"
        }
        if abs(pitch) >= 10 {
            return pitch > 0 ? "请稍微低头" : "请稍微抬头"
        }
        if abs(roll) >= 5 {
            return "请保持头部端正"
        }
        return nil
    }
}

3. 距离检测

class FaceDistanceDetector {
    func detectDistance(faceRect: CGRect, imageSize: CGSize) -> DistanceCondition {
        let faceRatio = (faceRect.width * faceRect.height) / (imageSize.width * imageSize.height)
        
        switch faceRatio {
        case ..<0.15:
            return .tooFar(suggestion: "请靠近一些")
        case 0.15..<0.25:
            return .slightlyFar(suggestion: "可以再靠近一点")
        case 0.25..<0.45:
            return .optimal
        case 0.45..<0.55:
            return .slightlyClose(suggestion: "可以稍微远一点")
        default:
            return .tooClose(suggestion: "请稍微远离镜头")
        }
    }
}

enum DistanceCondition {
    case tooFar(suggestion: String)
    case slightlyFar(suggestion: String)
    case optimal
    case slightlyClose(suggestion: String)
    case tooClose(suggestion: String)
    
    var isAcceptable: Bool {
        switch self {
        case .optimal, .slightlyFar, .slightlyClose:
            return true
        default:
            return false
        }
    }
}

4. 综合检测状态

struct PhotoCondition {
    let lighting: LightingCondition
    let angle: FaceAngle
    let distance: DistanceCondition
    let timestamp: Date
    
    var isReady: Bool {
        lighting.isAcceptable && angle.isOptimal && distance.isAcceptable
    }
    
    var suggestions: [String] {
        var result: [String] = []
        if case .tooDark(let s) = lighting { result.append(s) }
        if case .tooBright(let s) = lighting { result.append(s) }
        if let s = angle.suggestion { result.append(s) }
        if case .tooFar(let s) = distance { result.append(s) }
        if case .tooClose(let s) = distance { result.append(s) }
        return result
    }
}

UI引导组件

struct PhotoGuideOverlay: View {
    let condition: PhotoCondition
    
    var body: some View {
        ZStack {
            // 面部对齐框
            FaceAlignmentGuide(isAligned: condition.angle.isOptimal)
            
            // 状态指示器
            VStack {
                Spacer()
                ConditionIndicators(condition: condition)
                    .padding(.bottom, 100)
            }
            
            // 提示文字
            if !condition.isReady {
                SuggestionBanner(suggestions: condition.suggestions)
            }
        }
    }
}

struct FaceAlignmentGuide: View {
    let isAligned: Bool
    
    var body: some View {
        RoundedRectangle(cornerRadius: 120)
            .stroke(isAligned ? Color.green : Color.orange, lineWidth: 3)
            .frame(width: 240, height: 320)
    }
}

输出

struct StandardizedPhoto {
    let image: UIImage
    let metadata: PhotoMetadata
}

struct PhotoMetadata: Codable {
    let captureDate: Date
    let exposureValue: Double
    let faceAngle: FaceAngle
    let faceRatio: Double
    let deviceModel: String
}

验证

  • 光线检测准确
  • 角度检测灵敏度合适
  • 自动拍摄触发正确
  • UI引导清晰易懂
  • 支持无障碍(VoiceOver提示)