ARGB32 to YUV12 利用 SDL1.2 SDL_ttf 在视频表面输出文本
提示:ARGB alpha通道的A + 原YUV表面的y0 + 要写进去的y1 = 计算出新的y2.
计算公式为 ( y1 * a + y0 * ( 255 - a ) ) / 255
计算公式为 ( y1 * a + y0 * ( 255 - a ) ) / 255
void rgb2yuv(int r, int g, int b, int *y, int *u, int *v) { int y0, u0, v0; y0 = 66*r + 129*g + 25*b; u0 = -38*r + -74*g + 112*b; v0 = 112*r + -94*g + -18*b; y0 = (y0+128)>>8; u0 = (u0+128)>>8; v0 = (v0+128)>>8; *y = y0 + 16; *u = u0 + 128; *v = v0 + 128; } void yuv2rgb(int y, int u, int v, int *r, int *g, int *b) { int r0,g0,b0; v = v - 128; u = u - 128; r0 = y + v + (v>>2) + (v>>3) + (v>>5); g0 = y - ((u>>2) + (u>>4) + (u>>5)) - ((v>>1) + (v>>3) + (v>>4) + (v>>5)); b0 = y + u + (u>>1) + (u>>2) + (u>>6); *r = r0 > 255 ? 255: r0; *g = g0 > 255 ? 255: g0; *b = b0 > 255 ? 255: b0; } int blitSurface2YUV(SDL_Surface *src, SDL_Overlay *dst, SDL_Rect *dstrect ,int isBlended) { Uint8 r, g, b,a; int y0,u0,v0; int y1,u1,v1; int y2,u2,v2; int y,x; int height = src->h < dstrect->h ? src->h: dstrect->h; int width = src->w < dstrect->w ? src->w: dstrect->w; int uv_off = 0; Uint32 pixel; printf ("src->format->BitsPerPixel %d src->format %08X\r\n",src->format->BitsPerPixel,src->format); if(dst->format != SDL_YV12_OVERLAY)return 1; for(y = 0; y < height; ++y) { for(x = 0; x < width; ++x) { switch(src->format->BitsPerPixel) { case 8: pixel = *((Uint8*)src->pixels + y*src->pitch + x); break; case 16: pixel = *((Uint16*)src->pixels + y*src->pitch/2 + x); break; case 32: pixel = *((Uint32*)src->pixels + y*src->pitch/4 + x); break; default: return -1; } //SDL_GetRGB(pixel, src->format, &r, &g, &b); SDL_GetRGBA(pixel, src->format, &r, &g, &b,&a); rgb2yuv(r, g, b, &y1, &u1, &v1); if(isBlended) { y0 = (dst->pixels[0][ (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x)]); v0 = (dst->pixels[1][ (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2)]); u0 = (dst->pixels[2][ (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2)]); y2 = (Uint8)(( y1 * a + y0 * ( 255 - a ) ) / 255); u2 = (Uint8)(( u1 * a + u0 * ( 255 - a ) ) / 255); v2 = (Uint8)(( v1 * a + v0 * ( 255 - a ) ) / 255); y1=y2; u1=u2; v1=v2; } memset(dst->pixels[0] + (dstrect->y + y) * dst->pitches[0] + (dstrect->x + x), (Uint8)y1 , 1); if((x%2 == 0 ) && (y%2 == 0 )) { memset(dst->pixels[1] + (uv_off + dstrect->y /2) * dst->pitches[1] + (dstrect->x/2 + x/2), (Uint8)v1, 1); memset(dst->pixels[2] + (uv_off + dstrect->y /2) * dst->pitches[2] + (dstrect->x/2 + x/2), (Uint8)u1, 1); } } if(y%2 == 0)++uv_off; } return 0; }