[Solved] Image capture from webcam to jpg. lazarus / 39-Graphics ---------------------------------------------------------------------- BlueIcaro · 2020-11-23 19:51 Hello, I making a program that connects to a usb webcam using videodev2 that I get from sdpo package. I have any problem to capture a frame. But I want to save it as jpg format. Code: [Select] repeat     begin       FillChar(vBuf, sizeof(v4l2_buffer), 0);       vbuf._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;       vbuf.memory := V4L2_MEMORY_MMAP;       //Capturar imagen       if DynIoctl(videohandle, VIDIOC_DQBUF, @vbuf) < 0 then       begin         raise Exception.Create('Fallo durante la captura');       end;     end;   until vBuf.bytesused > 0;   VideoBufferIndex := vbuf.index;   FramePtr := VideoBuffer[VideoBufferIndex];   Datos := TMemoryStream.Create;   Datos.SetSize(vHeight * vWidth);   Datos.Position := 0;   size := vHeight * vWidth;   //   case PixelFormat of   //     uvcpf_YUYV:   //YUYV_to_Gray  function converted   for i := 0 to (size div 2) - 1 do   begin     g := FramePtr^ and $FF;     r := g;     b := g;     //dest^ := (r shl 16) or (g shl 8) or (b);     temp := (r shl 16) or (g shl 8) or (b);     Datos.Write(temp, SizeOf(Temp));     g := (FramePtr^ shr 16) and $FF;     r := g;     b := g;     //dest^ := (r shl 16) or (g shl 8) or (b);     temp := (r shl 16) or (g shl 8) or (b);     Datos.Write(temp, SizeOf(Temp));     Inc(FramePtr);     //Inc(dest);   end;        Imagen := TFPMemoryImage.Create(vWidth,vHeight);    Imagen.UsePalette:=true;     MiPaleta.Alpha:=0;    MiPaleta.Blue:=155;    MiPaleta.Green:=75;    MiPaleta.Red:=56;    f := Imagen.Palette.Add(MiPaleta);    DAtos.Position:=0;    For X:= 0 To Imagen.Width-1 do    begin       For Y := 0 To Imagen.Height-1 do       begin         pixel := Datos.ReadByte;         Imagen.Pixels[x,y] := pixel;       end;    end;   //   case PixelFormat of   //     uvcpf_YUYV:   //       YUYV_to_Gray(PLongWord(FramePtr), (pdatos),   //         vWidth * vHeight);   //     uvcpf_YUV420:   //       YUV420_to_Gray(FramePtr,  (pdatos), vWidth * vHeight);   //     uvcpf_RGB24:   //       RGB24_to_TrueColor(PRGB24Pixel(FramePtr),  (pdatos), vWidth * vHeight);   //     uvcpf_BGR24:   //       BGR24_to_TrueColor(PRGB24Pixel(FramePtr),  (pdatos), vWidth * vHeight);   //   end;      j := TFPWriterJPEG.Create;      j.CompressionQuality:=75;     Imagen.SaveToFile('pepe.jpg',j);                                                                                       In this code, I got a image from camera, and I convert to  YUYV_to_Gray and store into TMemorystream. But I'm lost with palette. I think I should create 255 palettes, which  values?. Or there is other way to do the job?. I attach all code. Programmed in Linux 20.04 and Lazarus 2.10 Thanks in advance /BlueIcaro ---------------------------------------------------------------------- circular · 2020-11-23 21:34 You can make a grayscale palette with a loop with i from 0 to 255, setting Red, Green and Blue to I*$0101 and alpha to $ffff ---------------------------------------------------------------------- Jurassic Pork · 2020-11-24 00:21 hello, if you have mplayer installed in your O.S and you  make a graphical program, have a look  here  and here Friendly, J.P ---------------------------------------------------------------------- BlueIcaro · 2020-11-24 17:40 Quote from: Jurassic Pork on November 24, 2020, 01:21:49 amhello, if you have mplayer installed in your O.S and you  make a graphical program, have a look  here  and here Friendly, J.P The program will run in a linux without GUI. /BlueIcaro ---------------------------------------------------------------------- BlueIcaro · 2020-11-25 15:19 Hello, I make some changes in the program. I can save a jpeg image. But my image is not equal to original is like rotate and cutted. This the code that I use to capture: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  procedure GuardarImagen; var  vBuf: v4l2_buffer;  VideoBufferIndex: __u32;  FramePtr: PByte;  x, y, i, size, f: integer;  Datos: TMemoryStream;  Imagen: TFPMemoryImage;  MiPaleta: TFPColor;  j: TFPWriterJPEG;  Convertido, src: PRGB24Pixel;  Blue, Green, Red, g, r, b: byte;  h, by, pixel: longint;  d, RgbColor: longword;  buffer: TRGB24Pixel;  color: TColor;  dest: Pointer; begin  repeat    begin      FillChar(vBuf, sizeof(v4l2_buffer), 0);      vbuf._type := V4L2_BUF_TYPE_VIDEO_CAPTURE;      vbuf.memory := V4L2_MEMORY_MMAP;    //Capturar imagen      if DynIoctl(videohandle, VIDIOC_DQBUF, @vbuf) < 0 then      begin        raise Exception.Create('Fallo durante la captura');      end;    end;   until vBuf.bytesused > 0;  Sleep(2000);  VideoBufferIndex := vbuf.index;  FramePtr := VideoBuffer[VideoBufferIndex];   Datos := TMemoryStream.Create;  //Datos.SetSize(vHeight * vWidth);  Datos.Position := 0;  size := vHeight * vWidth * 3;   case PixelFormat of    uvcpf_YUYV:      writeln('uvcpf_YUYV');    uvcpf_YUV420:      writeln('uvcpf_YUV420');    uvcpf_RGB24:      writeln('uvcpf_RGB24');    uvcpf_BGR24:      WriteLn('uvcpf_BGR24');  end;    //convers format uvcpf_BGR24  src := PRGB24Pixel(FramePtr);  for I := 0 to size - 1 do  begin    RgbColor := PLongWord(@src[I])^;    datos.Write(RgbColor,1);  end;   Imagen := TFPMemoryImage.Create(vWidth, vHeight);   Imagen.UsePalette := True;  for I := 0 to 255 do  begin    MiPaleta.Alpha := $FFFF;    MiPaleta.Blue := I * $0101;    MiPaleta.Green := I * $0101;    MiPaleta.Red := I * $0101;     f := Imagen.Palette.Add(MiPaleta);  end;     Datos.Position := 0;  for X := 0 to Imagen.Width - 1 do  begin    for Y := 0 to Imagen.Height - 1 do    begin      Datos.Read(RgbColor,1);      Imagen.Pixels[x, y] := RgbColor;    end;  end;     j := TFPWriterJPEG.Create;  j.CompressionQuality := 100;  Imagen.SaveToFile('pepe.jpg', j);end;          I attach the program complete. And two image. The "original" and the image that saves my program Any IdeaThanks/BlueIcaro ---------------------------------------------------------------------- circular · 2020-11-25 15:31 I suppose pixels are organized as rows, so: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Datos.Position := 0;  for Y := 0 to Imagen.Height - 1 do  begin    for X := 0 to Imagen.Width - 1 do    begin      Datos.Read(RgbColor,1);    Imagen.Pixels[x, y] := RgbColor;    end;  end; ---------------------------------------------------------------------- BlueIcaro · 2020-11-25 15:46 Amazing Circular!!! I was fighting with Tmemoruimage, and the tstreammemory, because I thought that the problem was when the programs moved the info from image buffer. Also I thought that the program leaved the repeat until loop before image was complete. I spend this days reading about linux driver  (  https://linuxtv.org/docs.php )  I didn't see that the rows are changed by cols  Two fast (i hope) questions more: How can I make a palette with the colors? Where Can I find more info about colors, palettes, etc? Thanks /BlueIcaro P.D I attach the image with Circular solution. The image is not the same that the previous post, because I moved the camera. ---------------------------------------------------------------------- circular · 2020-11-25 16:43 Basically you don't need to use the intermediate memory stream Datos nor Palette. You can set the RGB values directly: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var fpCol: TFPColor;...  Imagen := TFPMemoryImage.Create(vWidth, vHeight);  src := PRGB24Pixel(FramePtr);  fpCol.alpha := $ffff;  for Y := 0 to Imagen.Height - 1 do    for X := 0 to Imagen.Width - 1 do    begin    fpCol.red := src^.red * $101;      fpCol.green := src^.green * $101;      fpCol.blue := src^.blue * $101;      Imagen.Colors[x, y] := fpCol;      inc(src);    end;  ...  Imagen.Free; // don't forget to free memory ---------------------------------------------------------------------- BlueIcaro · 2020-11-26 20:04 Thank you very match for all /BlueIcaro