рд╣рд╛рд▓ рд╣реА рдореЗрдВ,
рдкрд┐рд▓реЛ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдпрд╣ рдкреНрд░рд╕рд┐рджреНрдз рдкреАрдЖрдИрдПрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдПрдХ рдХрд╛рдВрдЯрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЗрд╕рдХреА рдХрд╛рдлреА рдЙрдореНрд░ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдкрд╛рдпрдерди рдореЗрдВ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рдордЭрджрд╛рд░ рддрд░реАрдХрд╛ рдмрдирд╛ рд░рд╣рд╛ред рдкрд┐рд▓реЛ рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдиреЗ рдЖрдЦрд┐рд░рдХрд╛рд░ рди рдХреЗрд╡рд▓ рдкреБрд░рд╛рдиреЗ рдХреЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдмрд▓реНрдХрд┐ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рднреА рдЬреЛрдбрд╝рд╛ред рдФрд░ рдЗрдирдореЗрдВ рд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЕрд▓реНрдлрд╝рд╛_рдХрдореНрдкреЛрд╕рд┐рдЯ () рдлрд╝рдВрдХреНрд╢рди рдереАред
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рджреЛ рдкрд╛рд░рднрд╛рд╕реА рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рдорд┐рд╢реНрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдп рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рдкреГрд╖реНрдарднреВрдорд┐ рдкрд░ рдПрдХ рдЕрд▓реНрдлрд╛ рдЪреИрдирд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдЫрд╡рд┐ рдХреЛ рдУрд╡рд░рд▓реЗ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЖрдо рдорд╛рдорд▓рд╛ рд╣реИ, рдЬреЛ рд╢рд╛рдпрдж рдХрдИ рд▓реЛрдЧреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИред рдЖрдк
рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рдкрд░ рдкрд╛рд░рднрд╛рд╕реА рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рдорд┐рд╢реНрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ
рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ред
рддрдм рд╕реЗ, рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рдХ
рдЗрд╖реНрдЯрддрдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реВрдВред рдФрд░ рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди C рдореЗрдВ рд▓рд┐рдЦреЗ рддрдХрд┐рдпрд╛ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ Alpha_composite () рд╕реЗ рддреЗрдЬ рд╣реИред рдмреЗрд╢рдХ, рдореИрдВ рдЗрд╕рд╕реЗ рдЦреБрд╢ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдкрд┐рд▓реЛ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдмреЗрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
bench.pyfrom PIL import Image from timeit import repeat from image import paste_composite im1 = Image.open('in1.png') im1.load() im2 = Image.open('in2.png') im2.load() print repeat(lambda: paste_composite(im1.copy(), im2), number=100) print repeat(lambda: Image.alpha_composite(im1, im2), number=100) out1 = im1.copy() paste_composite(out1, im2) out1.save('out1.png') out2 = Image.alpha_composite(im1, im2) out2.save('out2.png')
рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡рд░реНрддрдорд╛рди рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкрдбрд╝реА рд╣реБрдИ in1.png рдФрд░ in2.png рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЗрддреА рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ paste_composite () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕реМ рдмрд╛рд░ рдкрд╣рд▓реЗ рдорд┐рд▓рд╛рддреА рд╣реИ, рдлрд┐рд░ Alpha_composite ()ред рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ (
рдПрдХ ,
рджреЛ ) рд╕реЗ рдлрд╛рдЗрд▓реЗрдВ рд▓реАрдВред Paste_composite () рдХрд╛ рдФрд╕рдд рд░рдирдЯрд╛рдЗрдо 235ms рдерд╛ред рдореВрд▓ Alpha_composite () рдХрд╛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рдордп 400ms рдерд╛ред
рдХреНрдпреЛрдВ рдЕрд▓реНрдлрд╛_рдХрдВрдкреЛрдЬрд┐рдЯ () рдЗрддрдирд╛ рдзреАрдорд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛рдирд╛ рд╣реИред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдлреНрд▓реЛрдЯрд┐рдВрдЧ рдкреЙрдЗрдВрдЯ рдирдВрдмрд░реЛрдВ рдкрд░ рд╕рднреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдлреНрд▓реЛрдЯрд┐рдВрдЧ-рдкреЙрдЗрдВрдЯ рдирдВрдмрд░ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХрд╛ рдкреНрд░рджрд░реНрд╢рди рд╣рдореЗрд╢рд╛ рдкреВрд░реНрдгрд╛рдВрдХ рд╕реЗ рдХрдо рд╣реЛрддрд╛ рд╣реИред рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рдореИрдВрдиреЗ рдХреА рдереА рд╡рд╣ рдкреВрд░реНрдгрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдЕрдиреБрд╡рд╛рдж рдХрд░ рд░рд╣реА рдереА:
typedef struct { UINT8 r; UINT8 g; UINT8 b; UINT8 a; } rgba8; Imaging ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { Imaging imOut = ImagingNew(imDst->mode, imDst->xsize, imDst->ysize); for (int y = 0; y < imDst->ysize; y++) { rgba8* dst = (rgba8*) imDst->image[y]; rgba8* src = (rgba8*) imSrc->image[y]; rgba8* out = (rgba8*) imOut->image[y]; for (int x = 0; x < imDst->xsize; x ++) { if (src->a == 0) { *out = *dst; } else { UINT16 blend = dst->a * (255 - src->a); UINT8 outa = src->a + blend / 255; UINT8 coef1 = src->a * 255 / outa; UINT8 coef2 = blend / outa; out->r = (src->r * coef1 + dst->r * coef2) / 255; out->g = (src->g * coef1 + dst->g * coef2) / 255; out->b = (src->b * coef1 + dst->b * coef2) / 255; out->a = outa; } dst++; src++; out++; } } return imOut; }
рдФрд░ рддреБрд░рдВрдд 5.5 рдЧреБрдирд╛ рдХреА рд╡реГрджреНрдзрд┐ рдкреНрд░рд╛рдкреНрдд рдХреАред рдкрд░реАрдХреНрд╖рдг рдиреЗ 75 рдПрдордПрд╕ рдореЗрдВ рдХрд╛рдо рдХрд┐рдпрд╛ред
рдПрдХ рдЕрдЪреНрдЫрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ рдХрд┐ рддрд╕реНрд╡реАрд░ рдХрд┐рддрдиреА рдЙрдЪреНрдЪ рдЧреБрдгрд╡рддреНрддрд╛ рд╡рд╛рд▓реА рдирд┐рдХрд▓реАред рдПрдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝реЛрдЯреЛрд╢реЙрдк рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реЗрдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рдореИрдВ рд╕рд╛рде рдирд╣реАрдВ рдЖрдпрд╛ред рдЙрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рджреЛ рдЫрд╡рд┐рдпрд╛рдВ рдлрд╝реЛрдЯреЛрд╢реЙрдк рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд▓реЛрдЧреЛрдВ рд╕реЗ рдЕрдкреНрд░рднреЗрджреНрдп рдереАрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдерд╛ рдХрд┐ рдорддрднреЗрджреЛрдВ рдХреЛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдЪрд┐рддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдЗрдирдкреБрдЯ рдкрд░, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде 2 рдлрд╝рд╛рдЗрд▓ рдирд╛рдореЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдЗрди рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбрд╝реЗ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рд╣реИрдВ: рдкрд╣рд▓рд╛, рдЕрдВрддрд░ рдмрд╕ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЧреНрд░реЗ рдкреГрд╖реНрдарднреВрдорд┐ (рдореВрд▓реНрдп 127) рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдк рджреЛрдиреЛрдВ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рд╡рд┐рдЪрд▓рди рджреЗрдЦ рд╕рдХреЗрдВред рддрдм рд╕рднреА рд╡рд┐рдЪрд▓рди, рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдореВрд▓реНрдп, 10 рдЧреБрдирд╛ рдмрдврд╝ рдЬрд╛рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╡реЗ рдиреЗрддреНрд░рд╣реАрди рджрд┐рдЦрд╛рдИ рджреЗрдВред рддреБрд▓рдирд╛ рдкрд░рд┐рдгрд╛рдо 2 рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ: diff.png рдореЗрдВ рдЖрд░рдЬреАрдмреА рдЪреИрдирд▓, diff.alpha.png рдореЗрдВ рдЧреНрд░реЗ рдХреЗ рд░рдВрдЧреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрд▓реНрдлрд╛ рдЪреИрдирд▓ред
рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ Alpha_composite () рдФрд░ рдлрд╝реЛрдЯреЛрд╢реЙрдк рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдХрд╛рдлреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ:

рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦрдиреЗ рдкрд░, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдореИрдВ рдЧреЛрд▓рд╛рдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреВрд▓ рдЧрдпрд╛ рдерд╛: рдкреВрд░реНрдгрд╛рдВрдХ рд╢реЗрд╖ рдХреЛ рдЫреЛрдбрд╝ рдХрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИрдВред рдпрджрд┐ рд╣рдо рдПрдХ рдЧреЛрд▓ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд▓рд╛рднрд╛рдВрд╢ рдореЗрдВ рдЖрдзрд╛ рд╡рд┐рднрд╛рдЬрдХ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
UINT16 blend = dst->a * (255 - src->a); UINT8 outa = src->a + (blend + 127) / 255; UINT8 coef1 = src->a * 255 / outa; UINT8 coef2 = blend / outa; out->r = (src->r * coef1 + dst->r * coef2 + 127) / 255; out->g = (src->g * coef1 + dst->g * coef2 + 127) / 255; out->b = (src->b * coef1 + dst->b * coef2 + 127) / 255; out->a = outa;
рд░рдирдЯрд╛рдЗрдо 94 рдПрдордПрд╕ рддрдХ рдмрдврд╝ рдЧрдпрд╛ред рд▓реЗрдХрд┐рди рд╕рдВрджрд░реНрдн рд╕реЗ рдмрд╣реБрдд рдХрдо рдЕрдВрддрд░ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡реЗ рдмрд┐рд▓реНрдХреБрд▓ рдЧрд╛рдпрдм рдирд╣реАрдВ рд╣реБрдПред
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╣рдо рдпрд╣рд╛рдВ рд░реБрдХ рд╕рдХрддреЗ рд╣реИрдВ: рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдореМрдЬреВрдж рд╡рд┐рд╕рдВрдЧрддрд┐рдпрд╛рдВ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЙрдЪреНрдЪ рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ рд╡рд╛рд▓реЗ рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИрдВ, рдЬреЛ рдХрд┐ рд░рдВрдЧ рдЪреИрдирд▓ рдореВрд▓реНрдп рдХреЛ рдЗрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рдмрдирд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрд▓реНрдлрд╝рд╛_рдХрдореНрдкреЛрдЬрд╝рд┐рдЯ () рдХреЗ рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдпрд╣ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдорд╛рдирдХ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╡рд╣рд╛рдВ рд░реБрдХрдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛ред
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдкреНрд░рд╛рдкреНрдд рдЕрд╢реБрджреНрдзрд┐ рдЧреБрдгрди рдХреЗ рджреМрд░рд╛рди рдЧреБрдгрд╛рдВрдХ рдХреА рдЕрдкрд░реНрдпрд╛рдкреНрдд рд╕рдЯреАрдХрддрд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рдЪрд░ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯреНрд╕ рд╕реНрдЯреЛрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╡рд┐рднрд╛рдЬрди рдХреА рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдорд┐рд╢реНрд░рдг рдЪрд░ рд╡рд┐рднрд╛рдЬрди рдХреЗ рдмрд┐рдирд╛ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЖрдЙрдЯ рдЪрд░ рдХреЛ рдорд┐рд╢реНрд░рдг рдХреЛ 255 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдорд┐рд╢реНрд░рдг рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╢рд┐рдлреНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ src-> рдПрдХ 4 рдмрд┐рдЯреНрд╕ рдЕрдк рдХрд░рддреЗ рд╣реИрдВред рдирддреАрдЬрддрди, рдЖрдЙрдЯрд╛ рдореЗрдВ 12 рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯреНрд╕ рд╣реЛрдВрдЧреЗред рджреЛрдиреЛрдВ рдЧреБрдгрд╛рдВрдХ рдореЗрдВ, рдЖрдЙрдЯ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднрд╛рдЬрди рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдЕрдм 4 рдмрд┐рдЯ рдмрдбрд╝рд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЧреБрдгрд╛рдВрдХ рд╕реНрд╡рдпрдВ 4 рдмрд┐рдЯ рдЕрдзрд┐рдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдирддреАрдЬрддрди, рд▓рд╛рднрд╛рдВрд╢ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 8 рдмрд┐рдЯреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
UINT16 blend = dst->a * (255 - src->a);
рдмреЗрд╢рдХ, рд╕рдорд╛рди 4 рдмрд┐рдЯреНрд╕ рдХреЛ рдЫрд╡рд┐ рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рд░рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рднреА рдЧрдгрдирд╛рдУрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдереЛрдбрд╝рд╛ рдзреАрдорд╛ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: 108 рдПрдордПрд╕, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рдЧрднрдЧ рдХреЛрдИ рдкрд┐рдХреНрд╕реЗрд▓ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдорд╛рдирдХ рд╕реЗ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдореВрд▓реНрдп рд╕реЗ рднрд┐рдиреНрди рд╣реЛред рдЧреБрдгрд╡рддреНрддрд╛ рдкрд░ рдкрд░рд┐рдгрд╛рдо рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЖрдк рдлрд┐рд░ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВред
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣ рдХреЛрдб рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рдирд╣реАрдВ рд╣реИред рдбрд┐рд╡реАрдЬрди рд╕рдмрд╕реЗ рдХрдард┐рди рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рд▓рд┐рдП 6 рд╡рд┐рднрд╛рдЬрди рдХрд┐рдП рдЧрдП рд╣реИрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред Paste.c рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рдорд╛рди PIL рдореЗрдВ, рдЧреЛрд▓рд╛рдИ рдХреЗ рд╕рд╛рде рддреЗрдЬрд╝ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рд╡рд░реНрдгрд┐рдд рд╣реИ:
a + 127 / 255 тЙИ ((a + 128) + ((a + 128) >> 8)) >> 8
рдирддреАрдЬрддрди, рдПрдХ рд╡рд┐рднрд╛рдЬрди рдХреЛ 2 рдкрд╛рд░рд┐рдпреЛрдВ рдФрд░ рдПрдХ рдЬреЛрдбрд╝ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рддреЗрдЬ рд╣реЛрддрд╛ рд╣реИред 4 рдХреА рдореМрдЬреВрджрд╛ рд╢рд┐рдлреНрдЯ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рд┐рдлреНрдЯ рдореЗрдВ рд╕рдореВрд╣реАрдХреГрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рдпрд╣ рдХреЛрдб рдорд┐рд▓рд╛:
UINT16 blend = dst->a * (255 - src->a); UINT16 outa = (src->a << 4) + (((blend << 4) + (blend >> 4) + 0x80) >> 8); UINT16 coef1 = (((src->a << 8) - src->a) << 8) / outa;
рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 65 рдПрдордПрд╕ рдореЗрдВ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдХрд╛рдо рдХреА рдЧрддрд┐ рдореЗрдВ 6 рдЧреБрдирд╛ рд╕реБрдзрд╛рд░ рд╣реБрдЖ, рдПрдХ рдкреВрд▓ рдЕрдиреБрд░реЛрдз рднрдВрдбрд╛рд░ рдХреЛ рднреЗрдЬрд╛ рдЧрдпрд╛ рдерд╛ред рдПрдХ рдорд╛рдирдХ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдорд╛рдирддрд╛ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдлрд╝реЛрдЯреЛрд╢реЙрдк рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдЕрд▓реНрдлрд╛ рдЪреИрдирд▓ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рджреЛрд╣рд░рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рд╡рд┐рд░реВрдкрдг рдХреЛ рдкрд┐рдХреНрд╕рд▓ рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдмрдбрд╝рд╛ рдЕрдкрдбреЗрдЯрдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдореИрдВрдиреЗ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдХрд┐ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдпрд╣ рддрдп рдХрд┐рдпрд╛ рдХрд┐ рдлрд╝реЛрдЯреЛрд╢реЙрдк рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд╣реЛрдЧрд╛ рдХрд┐ рдЬреЛ рдХрд╛рд░реНрдп рдХрд┐рдП рдЧрдП рд╣реИрдВ рдЙрдирдХреЗ рд▓рд┐рдП рдЕрдЬреНрдЮрд╛рдд рд╣реИ рдФрд░ рдЬрд┐рд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рднреА рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлреНрд▓реЛрдЯ рдкрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдПрдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореИрдВрдиреЗ рдЙрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬреЛ рдЕрдВрддрд░ рдкрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдХреБрдЫ рдЖрдВрдХрдбрд╝реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗред
рдореИрдВрдиреЗ 16 рдореЗрдЧрд╛рдкрд┐рдХреНрд╕реЗрд▓ рдкрд░ рджреЛ рдЪрд┐рддреНрд░реЛрдВ рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рдЧрдВрднреАрд░ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛, рдЬрд╣рд╛рдБ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рд╕рдВрдпреЛрдЬрди рдЕрджреНрд╡рд┐рддреАрдп рдерд╛ред
make_testcase.py def prepare_test_images(dim): """Plese, be careful with dim > 32. Result image is have dim ** 4 pixels (ie 1Mpx for 32 dim or 4Gpx for 256 dim). """ i1 = bytearray(dim ** 4 * 2) i2 = bytearray(dim ** 4 * 2) res = 255.0 / (dim - 1) rangedim = range(dim) pos = 0 for l1 in rangedim: for l2 in rangedim: for a1 in rangedim: for a2 in rangedim: i1[pos] = int(res * l1) i1[pos + 1] = int(res * a1) i2[pos] = int(res * l2) i2[pos + 1] = int(res * a2) pos += 2 print '%s of %s' % (l1, dim) i1 = Image.frombytes('LA', (dim ** 2, dim ** 2), bytes(i1)) i2 = Image.frombytes('LA', (dim ** 2, dim ** 2), bytes(i2)) return i1.convert('RGBA'), i2.convert('RGBA') im1, im2 = prepare_test_images(63) im1.save('im1.png') im2.save('im2.png')
рдЙрд╕рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рджреВрд╕рд░реЗ рдЫреЛрд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛: рдкреВрд░реНрдгрд╛рдВрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рд╕рдЯреАрдХрддрд╛ рдмрдврд╝рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдкреВрд░реНрдгрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлреНрд▓реЛрдЯрд┐рдВрдЧ-рдкреЙрдЗрдВрдЯ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдореИрдВрдиреЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдерд╛:
double dsta = dst->a / 255.0; double srca = src->a / 255.0; double blend = dsta * (1.0 - srca); double outa = srca + blend; double coef1 = srca / outa; double coef2 = 1 - coef1; double tmpr = src->r * coef1 + dst->r * coef2; out->r = (UINT8) (tmpr + 0.5); double tmpg = src->g * coef1 + dst->g * coef2; out->g = (UINT8) (tmpg + 0.5); double tmpb = src->b * coef1 + dst->b * coef2; out->b = (UINT8) (tmpb + 0.5); out->a = (UINT8) (outa * 255.0 + 0.5);
рдФрд░ рдпрд╣реА рдореИрдВ рдЖрдпрд╛:
UINT16 blend = dst->a * (255 - src->a); UINT16 outa255 = src->a * 255 + blend;