ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Possible image corruption during Exif rotation?

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
rtvdoorn Posted - Dec 04 2019 : 07:14:38
Hi,

Using ImageEn 8.6.0 and Delphi Rio 10.3.1 developing a 32 bit application, we use the code below in a background thread to:
* determine Exif rotation flag
* load the file and auto-rotate it
* remove the flag(s) and
* save it again, after which we reload the image

A few of our customers are reporting issues with image getting weird lines and dots on them. All of these images are portrait images that were auto-rotated to contain no Exif rotation information. Is it possible this code cannot be used in a background thread? Can you advice on an approach that would work? We have not been able to reproduce this ourselves, but it is reported by multiple customers with images from multiple types of devices (iPhones, Canon DSLRs).


  io := TImageEnIO.Create(nil);
  try
    ieParams := io.Params;

    io.ParamsFromFile(AFileName);
    //do not change jpeg quality to lower
    io.Params.JPEG_Quality := 100;
    if ieParams.EXIF_HasEXIFData and
       ((ieParams.EXIF_Orientation <> 0) or (ieParams.TIFF_Orientation <> 0)) 
    then
    begin
      ieParams.EnableAdjustOrientation := true;
      io.LoadFromFile(AFileName);

      ieParams.EXIF_Orientation := 0;
      ieParams.TIFF_Orientation := 0;
      ieParams.EXIF_Bitmap.Clear;
      io.SaveToFile(AFileName);
    end;
  finally
    io.Free;
  end;


Effects that our customers experience:

Original (unrotated):



Affected (rotated, same part of the image included):

4   L A T E S T    R E P L I E S    (Newest First)
rtvdoorn Posted - Dec 09 2019 : 04:11:38
Hi Nigel, thank you for your response.

We do not cancel any background threads, nor is the file being used by other threads. This thread is (at the moment this code is runnning) the only thread we created to run in the background.
We are however searching for a different suspect now, where one of our other included 3rd party libraries apparently messes around with the GDI+ settings, more specifically that library sets GDI+ to suppress the background thread.

Thank you for your assistance so far. I think we will need to investigate this outside multi-threading and ImageEn.

- Roald
xequte Posted - Dec 06 2019 : 13:49:02
Hi

Yes, ImageEn should be fully thread safe in that situation.

We tried embedding your code inside a TThread and to execute it continuously (code below). The resulting jpeg is always good.

It seems that the produced file has some bytes corrupted. So saving may be working correctly (interrupted by something?) or there another processing is writing the same file.

Some questions:
1) How many threads do you run concurrently?
2) Is it possible that the background thread is stopped for some reason (maybe by closing a form or the application)?


type
TMyThread = class(TThread)
private

public
  constructor Create(CreateSuspended:Boolean);
  procedure Execute(); override;

end;


var
  mythread: TMyThread;

procedure TForm1.Button1Click(Sender: TObject);
begin
  mythread := TMyThread.Create(false);
end;


constructor TMyThread.Create(CreateSuspended:Boolean);
begin
    inherited Create;
end;

procedure TMyThread.Execute();
var
  io: timageenio;
  ieParams: TIOParams;
  AFileName, OFileName: string;
begin
  AFileName := 'C:\DSC04031.JPG';
  OFileName := 'c:\test.jpeg';

  while True do
  begin

    io := TImageEnIO.Create(nil);
    try
      ieParams := io.Params;

      io.ParamsFromFile(AFileName);
      //do not change jpeg quality to lower
      io.Params.JPEG_Quality := 100;
      if ieParams.EXIF_HasEXIFData and
         ((ieParams.EXIF_Orientation <> 0) or (ieParams.TIFF_Orientation <> 0))
      then
      begin
        ieParams.EnableAdjustOrientation := true;
        io.LoadFromFile(AFileName);

        ieParams.EXIF_Orientation := 0;
        ieParams.TIFF_Orientation := 0;
        ieParams.EXIF_Bitmap.Clear;
        io.SaveToFile(OFileName);
      end;
    finally
      io.Free;
    end;

  end;
end;



Nigel
Xequte Software
www.imageen.com
rtvdoorn Posted - Dec 05 2019 : 04:50:54
Hi Nigel, I am unfamiliar with the phrase "torture testing."
In any case, the screenshots I added are a part of the original customer's photo and the end result after the customer loaded it into our software.
I have been unable to reproduce this issue myself with the same images. Is ImageEn safe to use in threads like we do? Is there any other possible
cause that might cause these artifacts?
xequte Posted - Dec 04 2019 : 13:47:01
Hi

Have you tried asking the customers for the source images, then doing some torture testing to see if you can reproduce the issue?

Nigel
Xequte Software
www.imageen.com