Author |
Topic  |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 15 2012 : 23:21:34
|
I have an image scanned into an ImageEnVect at 150 DPI and some objects like rectangles are drawn on it and saved to a .iev file. But when an image of a different DPI is loaded into the Image such as a 300 DPI image, loading the objects back from the .iev file is no longer true to the size. How can I load the objects to their true size of the image in the ImageEnVect based on the DPI?
Thanks. |
|
fab
   
1310 Posts |
Posted - Feb 15 2012 : 23:40:34
|
Objects coordinates (and sizes) are relative to the image measured in pixels. Also, objects maintain their coordinates, in pixels, when reloaded.
|
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 00:10:41
|
I am using ObjLeft, ObjTop, etc. to get the coordinates in order to crop out the image defined by IEBOX rectangles. Maybe this is where I have a problem.
After loading another DPI image like 300 DPI, I load the .iev file (created from the 150 DPI image file), iterate through the objects and using ObjLeft, ObjTop, etc. values to CropSel the image pieces out. But somehow, the image pieces are wrong due to the size change. What would be the correct way to do this or if there is an easier way to crop out all the objects in one go?
Thanks.
|
 |
|
fab
   
1310 Posts |
Posted - Feb 16 2012 : 00:49:11
|
Please do not consider DPI when dealing with objects: they relate only pixels. Anyway, please could you provide a project (with sample images) that shows this problem? Maybe it could be a starting point for a future improvement. |
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 09:34:00
|
>Objects coordinates (and sizes) are relative to the image measured in pixels. >Also, objects maintain their coordinates, in pixels, when reloaded.
If an .iev file is created using an image that is smaller, are you saying that if another image that is bigger is loaded and the same .iev file is then loaded, the .iev will automatically adjust to the size of the new image? I am unable to make this work. Could it be that TimageEnVect.SelectionBase is wrong? Or do I have to set the pixel size of the TImageEnVect?
|
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 09:38:15
|
Here is a snapshot of how it looks like for my problem. This is after loading a larger image but loading an .iev created from a smaller image.
 42.65 KB |
 |
|
fab
   
1310 Posts |
Posted - Feb 16 2012 : 09:41:49
|
quote: If an .iev file is created using an image that is smaller, are you saying that if another image that is bigger is loaded and the same .iev file is then loaded, the .iev will automatically adjust to the size of the new image?
No, it is exactly the opposite. Coordinates of objects are restored as is. If you need to move/resize them, to adapt to the new image size, then you have to do it manually (or resize the image).
If you create a box at position 0,0 with width=100 and height=100, then it will be restored (after LoadFromFileIEV) at the same position and with the same size, independently by the current background image. |
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 10:07:20
|
If after loading an image and loading the .iev file, is there a way to resample the image and the objects according? Right now, resample the image does not resample the objects. |
 |
|
fab
   
1310 Posts |
Posted - Feb 16 2012 : 10:29:17
|
You have to resample objects manually. They are not related (anchored) with the background image. Following is a loop which move/resize all objects by a multiplier (1.2 in this example):
var
i, hobj: integer;
multiplier: double;
rect: TRect;
begin
multiplier := 1.2; <--- application specific
for i:=0 to ImageEnVect1.ObjectsCount-1 do
begin
hobj := ImageEnVect1.GetObjFromIndex(i);
ImageEnVect1.GetObjRect(hobj, rect);
rect.Left := round(rect.Left * multiplier);
rect.Top := round(rect.Top * multiplier);
rect.Right := round(rect.Right * multiplier);
rect.Bottom := round(rect.Bottom * multiplier);
ImageEnVect1.SetObjRect(hobj, rect);
end;
end;
Of course multiplier is application specific. I don't know how your images are and how objects are anchored when the image size change. Maybe, if you create objects for an image of 150 DPI and then you load the same image with 300 DPI, then multiplier could be 2.0.
Also, that code doesn't handle resampling of text font sizes.
|
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 10:45:21
|
Can the multiplier be calculated from the pixel width and height?
For example, if the new width is N2 and the old width is N1, then the multiplier for width is Round( N2 / N1 )?
|
 |
|
fab
   
1310 Posts |
Posted - Feb 16 2012 : 10:58:56
|
quote: For example, if the new width is N2 and the old width is N1, then the multiplier for width is Round( N2 / N1 )?
This is application specific. N2/N1 could be a reasonable value but what about the vertical size? Does it maintain aspect ratio? |
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 11:13:01
|
Fabrizio,
It does not seem to work when cropping out the images:
perW := 300 / 72; //New DPI X / Old DPI X perH := 300 / 72; //New DPI Y / Old DPI Y
for k := 0 to ImageEnViewMaster.ObjectsCount - 1 do begin hobj := ImageEnViewMaster.GetObjFromIndex(k);
ImageEnViewMaster.GetObjRect(hobj, rect); rect.Left := round(rect.Left * perW); rect.Top := round(rect.Top * perH); rect.Right := round(rect.Right * perW); rect.Bottom := round(rect.Bottom * perH);
TempImageEnView.Blank; TempImageEnView.IO.LoadFromFile( FTempScanFile ); TempImageEnView.Proc.Crop(rect.Left, rect.Top, rect.Right, rect.Bottom); TempImageEnView.Update;
targetfile := IncludeTrailingPathDelimiter( Trim( TargetRealEdit.Text ) ) + Trim( PrefixEdit.Text ) + Format('_%4.4d', [scount]) + sExt;
case FormatComboBox.ItemIndex of 0: begin TempImageEnView.IO.SaveToFileBMP( targetfile ); end; 1: begin TempImageEnView.IO.SaveToFileJpeg( targetfile ); end; 2: begin TempImageEnView.IO.SaveToFileJP2( targetfile ); end; 3: begin TempImageEnView.IO.SaveToFileTIFF( targetfile ); end; 4: begin TempImageEnView.IO.SaveToFilePNG( targetfile ); end; end;
scount := scount + 1;
end;
Where did I go wrong?
|
 |
|
fab
   
1310 Posts |
Posted - Feb 16 2012 : 11:16:42
|
Where is SetObjRect? I don't understand very well what your code should do, I'm sorry! |
 |
|
AndyColmes
  
USA
351 Posts |
Posted - Feb 16 2012 : 11:25:26
|
I think I got it right and it seems to work. As for the code, I am just getting the coordinates so I can use TImageEnVect.Proc.Crop to crop out the individual images defined by each rectangle object.
Thanks again, Fabrizio.
|
 |
|
|
Topic  |
|