# -*- coding: utf-8 -*-
"""Tạo ẢNH ZOOM 5+ ĐIỂM cho mẫu (bắt buộc theo yêu cầu chủ dự án 06/10/2026) + đo màu trung bình từng điểm (sRGB -> L*a*b*).
Kết quả: anh_mau_moi\\zoom_*.jpg  +  file _zoom_do_mau.txt (số liệu đo được, không để AI tự đoán).
"""
import io, os, sys

D = r'C:\Claw 2\Nghien cuu\Du-an-A-Quy-trinh-son'
ND = os.path.join(D, 'anh_mau_moi')
try:
    from PIL import Image, ImageStat
except ImportError:
    print('KHÔNG CÓ Pillow:', sys.executable)
    sys.exit(1)

def srgb_to_lab(r, g, b):
    def f(c):
        c /= 255.0
        return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4
    r, g, b = f(r), f(g), f(b)
    x = r * 0.4124 + g * 0.3576 + b * 0.1805
    y = r * 0.2126 + g * 0.7152 + b * 0.0722
    z = r * 0.0193 + g * 0.1192 + b * 0.9505
    xn, yn, zn = 0.95047, 1.0, 1.08883
    def g2(t):
        return t ** (1 / 3) if t > 0.008856 else (7.787 * t + 16 / 116)
    fx, fy, fz = g2(x / xn), g2(y / yn), g2(z / zn)
    return 116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)

mau = [f for f in sorted(os.listdir(ND)) if f.startswith('mau_') and f.lower().endswith(('.jpg', '.jpeg', '.png'))]
if not mau:
    print('KHÔNG có ảnh mẫu mau_* trong', ND); sys.exit(1)
src = os.path.join(ND, mau[0])
im = Image.open(src).convert('RGB')
W, H = im.size
print('ảnh mẫu:', mau[0], '%dx%d' % (W, H))

diem = [('1_giua', 0.50, 0.50), ('2_trai-tren', 0.16, 0.18), ('3_phai-tren', 0.84, 0.22),
        ('4_trai-duoi', 0.22, 0.78), ('5_phai-duoi', 0.78, 0.82), ('6_giua-duoi', 0.50, 0.90)]
lines = ['NGUỒN: %s (%dx%d)' % (mau[0], W, H), '']
for ten, fx, fy in diem:
    w = int(W * 0.30); h = int(H * 0.30)
    x0 = max(0, min(W - w, int(W * fx - w / 2))); y0 = max(0, min(H - h, int(H * fy - h / 2)))
    c = im.crop((x0, y0, x0 + w, y0 + h))
    z = c.resize((w * 3, h * 3), Image.LANCZOS)
    p = os.path.join(ND, 'zoom_%s.jpg' % ten)
    z.save(p, quality=95)
    st = ImageStat.Stat(c)
    r, g, b = [int(round(v)) for v in st.mean[:3]]
    L, A, B = srgb_to_lab(r, g, b)
    sd = sum(st.stddev[:3]) / 3
    lines.append('zoom_%s.jpg  | vùng %d%%×%d%% quanh (%d%%,%d%%) | RGB %d,%d,%d  #%02X%02X%02X | L* %5.1f  a* %5.1f  b* %5.1f | mức biến thiên (SD) %.1f'
                 % (ten, 30, 30, int(fx * 100), int(fy * 100), r, g, b, r, g, b, L, A, B, sd))
    print(lines[-1])
# thêm 2 ô chi tiết: vùng TỐI NHẤT và vùng SÁNG NHẤT (12%) để soi ghim sớ / vân
# loại trừ mép ngoài 6% và các điểm gần trắng (mép giấy/nhãn) để không chọn nhầm
gray = im.convert('L')
w2, h2 = int(W * 0.12), int(H * 0.12)
small = gray.resize((max(1, W // 10), max(1, H // 10)))
sw, sh = small.size
px = list(small.getdata())
for i in range(sw * sh):
    gx, gy = (i % sw) * 10, (i // sw) * 10
    if gx < W * 0.06 or gy < H * 0.06 or gx > W * 0.88 or gy > H * 0.88:
        px[i] = 128  # mép ngoài: bỏ qua
imin = px.index(min(px)); imax = px.index(max(px))

for ten, idx in (('7_vung-toi-nhat', imin), ('8_vung-sang-nhat', imax)):
    gx, gy = (idx % sw) * 10, (idx // sw) * 10
    x0 = max(0, min(W - w2, gx)); y0 = max(0, min(H - h2, gy))
    c = im.crop((x0, y0, x0 + w2, y0 + h2)).resize((w2 * 3, h2 * 3), Image.LANCZOS)
    c.save(os.path.join(ND, 'zoom_%s.jpg' % ten), quality=95)
    st = ImageStat.Stat(c)
    r, g, b = [int(round(v)) for v in st.mean[:3]]
    L, A, B = srgb_to_lab(r, g, b)
    lines.append('zoom_%s.jpg  | ô 12%%×12%% tại (%d,%d) | RGB %d,%d,%d  #%02X%02X%02X | L* %5.1f  a* %5.1f  b* %5.1f'
                 % (ten, x0, y0, r, g, b, r, g, b, L, A, B))
    print(lines[-1])
io.open(os.path.join(ND, '_zoom_do_mau.txt'), 'w', encoding='utf-8').write('\n'.join(lines) + '\n')
print('\nđã ghi', len(lines) - 2, 'ô zoom + file _zoom_do_mau.txt')
