Fast method to copy memory with translation - ARGB to BGR

前端 未结 11 1917
野趣味
野趣味 2020-12-07 10:47

Overview

I have an image buffer that I need to convert to another format. The origin image buffer is four channels, 8 bits per channel, Alpha, Red, Green, and Blue

11条回答
  •  没有蜡笔的小新
    2020-12-07 11:41

    I haven't seen anyone showing an example of how to do it on the GPU.

    A while ago I wrote something similar to your problem. I received data from a video4linux2 camera in YUV format and wanted to draw it as gray levels on the screen (just the Y component). I also wanted to draw areas that are too dark in blue and oversaturated regions in red.

    I started out with the smooth_opengl3.c example from the freeglut distribution.

    The data is copied as YUV into the texture and then the following GLSL shader programs are applied. I'm sure GLSL code runs on all macs nowadays and it will be significantly faster than all the CPU approaches.

    Note that I have no experience on how you get the data back. In theory glReadPixels should read the data back but I never measured its performance.

    OpenCL might be the easier approach, but then I will only start developing for that when I have a notebook that supports it.

    (defparameter *vertex-shader*
    "void main(){
        gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
        gl_FrontColor  = gl_Color;
        gl_TexCoord[0] = gl_MultiTexCoord0;
    }
    ")
    
    (progn
     (defparameter *fragment-shader*
       "uniform sampler2D textureImage;
    void main()
    {
      vec4 q=texture2D( textureImage, gl_TexCoord[0].st);
      float v=q.z;
      if(int(gl_FragCoord.x)%2 == 0)
         v=q.x; 
      float x=0; // 1./255.;
      v-=.278431;
      v*=1.7;
      if(v>=(1.0-x))
        gl_FragColor = vec4(255,0,0,255);
      else if (v<=x)
        gl_FragColor = vec4(0,0,255,255);
      else
        gl_FragColor = vec4(v,v,v,255); 
    }
    ")
    

    enter image description here

提交回复
热议问题