• Welcome to Vampyre Imaging Library Forum. Please login or sign up.
 

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - mjoyner@vbservices.net

1
Really not sure where your classes end and the LCL stuff begins. Just know that I read that I needed your classes to load image with automatic detection of image type and also using your functions for basic image rotate and scale operations at the moment.

Here is a copy of the subroutine.

Code (pascal) Select

function processImage(Filename: UTf8String): imgInfo;
  const
  {$J+}
    image: TSingleImage = nil;
    png: TImagingPNG = nil;
    jpg: TImagingJpeg = nil;
  {$J-}
  var
    info: imgInfo;
    tmpFile: UTF8String;
    tmpJPG: UTF8String;
    tmpPNG: UTF8String;
    scaleByH: double;
    scaleByW: double;
    scaleBy: double;
    newWidth: longint;
    newHeight: longint;
    jpgQuality: longint;
  begin
    //info=imgInfo;
    if UI.cbShowDebug.Checked then frmDebug.ShowOnTop;
    if image = nil then begin
      image := TSingleImage.Create;
      png := TImagingPNG.Create;
      jpg := TImagingJpeg.Create;
      end;
    {load image}
    image.Clear;
    frmDebug.memoDebug.Append(Filename);
    image.LoadFromFile(Filename);

    {basic transforms to ensure internal consistancy}
    ConvertImage(image.ImageDataPointer^, ifA32R32G32B32F);

    frmDebug.memoDebug.Append('Size: ' + IntToStr(image.Width) + 'x' +
      IntToStr(image.Height));

    {rotate check?}
    if UI.cbRotate.Checked then if portrait then begin
        if (image.Width > image.Height) then begin
          UI.ProcessMessages;
          RotateImage(image.ImageDataPointer^, 90);
          frmDebug.memoDebug.Append('Rotated Size: ' + IntToStr(image.Width) +
            'x' + IntToStr(image.Height));
          end;
        end else {landscape} if (image.Height > image.Width) then begin
          UI.ProcessMessages;
          RotateImage(image.ImageDataPointer^, -90);
          frmDebug.memoDebug.Append('Rotated Size: ' + IntToStr(image.Width) +
            'x' + IntToStr(image.Height));
          end;

    {rescale check?}
    if UI.cbRescale.Checked then begin
      {rescale down maxpect}
      frmDebug.memoDebug.Append('Maxpect Size: ' + IntToStr(imageMaxpectWidth) +
        'x' + IntToStr(imageMaxpectHeight));
      UI.ProcessMessages;
      scaleByW := imageMaxpectWidth / (image.Width * 1.0);
      scaleByH := imageMaxpectHeight / (image.Height * 1.0);

      if ((scaleByW < 1) or (scaleByH < 1)) then begin
        if scaleByW < scaleByH then scaleBy := scaleByW
        else
          scaleBy := scaleByH;
        newWidth := Round(scaleBy * image.Width);
        newHeight := Round(scaleBy * image.Height);
        ResizeImage(image.ImageDataPointer^, newWidth, newHeight, rfBicubic);
        frmDebug.memoDebug.Append('New Size: ' + IntToStr(image.Width) +
          'x' + IntToStr(image.Height));
        end;

      {rescale up maxpect}
      if (scaleByW > 1) and (scaleByH > 1) then begin
        if scaleByW < scaleByH then scaleBy := scaleByW
        else
          scaleBy := scaleByH;

        newWidth := Round(scaleBy * image.Width);
        newHeight := Round(scaleBy * image.Height);
        ResizeImage(image.ImageDataPointer^, newWidth, newHeight, rfBicubic);
        frmDebug.memoDebug.Append('New Size: ' + IntToStr(image.Width) +
          'x' + IntToStr(image.Height));

        end;
      end;

    {work around Red/Blue swap on Assign issue, all further
    assigns will swap the Red/Blue back to correctness, if the
    bug does not exist (WIN32 for example), it is just extra
    data being moved around with only a minor cpu impact}

    png.AssignFromImage(image);
    png.AssignToImageData(image.ImageDataPointer^);

    {save as temporary png file}
    tmpPNG := mkstemp;
    png.AssignFromImage(image);
    png.CompressLevel := 9;
    png.PreFilter := 6;
    png.SaveToFile(tmpPNG);

    {save as temporary jpg file}
    tmpJPG := mkstemp;
    jpg.AssignFromImage(image);
    jpgQuality:=UI.seJpgQ.Value;


    jpg.Quality := jpgQuality;
    jpg.SaveToFile(tmpJPG);

    if  (FileSize(tmpPNG)>(UI.seJpgSize.Value*1024)) then begin
        while (FileSize(tmpJPG) > UI.seJpgSize.Value*1024)
        and (jpgQuality>=0) do begin
            jpgQuality -= 1;
            jpg.Quality := jpgQuality;
            jpg.SaveToFile(tmpJPG);
        end;
    end;


    {which is smaller?}
    if (FileSize(tmpJPG) < FileSize(tmpPNG)) then tmpFile := tmpJPG
    else
      tmpFile := tmpPNG;
    Result[0] := tmpFile;
    Result[1] := DetermineFileFormat(tmpFile);
    Result[2] := IntToStr(image.Width);
    Result[3] := IntToStr(image.Height);
    Result[4] := '';

  end;           
2
I found out it is happening during an ASSIGN op:

Code (pascal) Select


    tmpJPG := mkstemp;
    image.SaveToFile('/tmp/test.jpg');
    image.SaveToFile('/tmp/test.png');
    jpg.AssignFromImageData(image.ImageDataPointer^);
    jpg.Quality := Comics2ePubUI.seJpgQ.Value;
    jpg.SaveToFile(tmpJPG);                         



I have tried:

jpg.Assign(image)
jpg.AssignFromImageData(image.ImageDataPointer^)
jpg.AssignFromImage(image)


....


OK, I think I found wherein it lies.

It is specifically the Assign and AssignFromImage*

Code (pascal) Select


const
  {$J+}
    image: TSingleImage = nil;
    imageSwap: TSingleImage = nil;
    png: TImagingPNG = nil;
    jpg: TImagingJpeg = nil;
  {$J-}
  var
    info: imgInfo;
    tmpFile: UTF8String;
    tmpJPG: UTF8String;
    tmpPNG: UTF8String;
    scaleByH: double;
    scaleByW: double;
    scaleBy: double;
    newWidth: longint;
    newHeight: longint;
  begin
      image := TSingleImage.Create;
      png := TImagingPNG.Create;
      jpg := TImagingJpeg.Create;     

{work around Red/Blue swap on Assign issue, all further
    assigns will swap the Red/Blue back to correctness, if the
    bug does not exist (WIN32 for example), it is just extra
    data being moved around with only a minor cpu impact}

    png.AssignFromImage(image);
    png.AssignToImageData(image.ImageDataPointer^);       


The AssignTo does not seem to be impacted.
3
Quote from: mjoyner@vbservices.net on 12 December 2011, 01:37:15
Quote from: Galfar on 12 December 2011, 00:15:53
Hello,

Did this work before you downloaded "working"?

Could you try ifA8R8G8B8 instead of ifA32R32G32B32F in the conversion?





Perhaps a CPU32 vs CPU64 thing?


changing format = no change in channel swap

4
Quote from: Galfar on 12 December 2011, 00:15:53
Hello,

Did this work before you downloaded "working"?

Could you try ifA8R8G8B8 instead of ifA32R32G32B32F in the conversion?

What file formats have you loaded from/saved to?


a) It wouldn't compile which is why I am using "working".
b) Will give said format a try in a bit and report back.
c) loading from gif, png, jpg, saving to png, jpg
d) just loaded 32-bit lazarus on my windows vm, it doesn't swap colors (what a painful experience..)

Have also discovered that "FileOpen" FHANDLE can hold "-1" on linux/x64 but shows up instead as 4294967295 when assigned -1 on W32 ???

Perhaps a CPU32 vs CPU64 thing?


5
Hello,

Thanks for this library!

Downloaded the latest "working" and all the images I load and save have the red and blue channels swapped.

If I put this:

Code (pascal) Select


image.LoadFromFile(Filename);

    {basic transforms to ensure internal consistancy}
    ConvertImage(image.ImageDataPointer^, ifA32R32G32B32F);

    {work around Blue/Red channel swap bug}
    image.SwapChannels(ChannelRed, ChannelBlue);



It seems to help.

I am Ubuntu, X64, Lazarus 0.9.30.2-0, FPC Version: 2.4.4, GTK2
SMF spam blocked by CleanTalk