T O P I C R E V I E W |
jenswahl |
Posted - Jul 18 2013 : 06:12:39 Hello,
I want to work on photos (or scans) with pages of a comic. Mostly the photo shows more than only the wanted page (a black background). To get only the page I use this code:
var
ievSrc: TImageEnView;
iebmTmp: TIEBitmap;
ioTmp: TImageEnIO;
ptTmp: TPoint; //it's the point to get the background color
begin
...
//get ptTmp....
...
//beginning of getting the page
ievSrc.MagicWandMaxFilter := True;
ievSrc.MagicWandTolerance := 40;
ievSrc.MagicWandMode := iewExclusive;
ievSrc.SelectMagicWand(ptTmp.X, ptTmp.Y, iespReplace);
//here I see the selected page correctly
ievSrc.InvertSelection;
//copy the selection into a temp iebitmap for saving
iebmTmp:=IEBitmap.Create;
ioTmp := TImageEnIO.Create(nil);
ievSrc.CopySelectionToIEBitmap(iebmTmp);
ioTmp.AttachedIEBitmap := iebmTmp;
//I get the complete photo with white background!
ioTmp.SaveToFile('c:\Test\example.jpg');
ioTmp.Free;
ievSrc.DeSelect;
ievSrc.Blank;
ievSrc.IEBitmap.Assign(iebmTmp);
//I see only the wanted page
ievSrc.Update;
iebmTmp.Free;
...
end;
The background on the photo is near black (second attatched file). At last I can show the page correctly on the ievSrc. But if I save it as a file from ievSrc (and also by saving iebmTmp) I have the same size like the original only with a white background (first attatched file).
How can I get a saved file only with the wanted page?
Best regards
Jens

 |
8 L A T E S T R E P L I E S (Newest First) |
jenswahl |
Posted - Jul 24 2013 : 02:35:36 Hello,
a little summary: my test-application runs now with good results. It works with photos or scanned images with a black (or other colored) background. The wanted page can be rotated and must not be centered in the photo. But a requirement is that a part of the wanted page lies on the centre of the photo.
What have I done: Firstly I set the background color to transparency (and not to a not used color: thanks to w2m). Than I scan from the center of the photo to the left, right, upper and lower border where transparency begins. Using two helper points on the upper border I get the rotation angle of the page. If this angle = 0 then it's easy to get the corner points of the page. If the angle <> 0 I have to use some trigonometric functions to get these points. In the end I have 8 points for creating the selection (point 9 of the array is the centre of the photo). I have the front and rear page as a single page on a photo, the other pages are double pages on a photo. So I select the single pages automatically too. After selection I copy the selection into another TIEBitmap, rotate it if angle <> 0 and save it. The results are mostly good. For 9 photos with double pages and the front plus the rear page-photos (11 all with about 8 mega pixels each) it needs between 2:30 minutes till 3:00 minutes (the last if I have to rotate all pages). I have to do some fine tuning but this is OK. So the problem is solved to me. Thanks for all the help.
Jens
|
jenswahl |
Posted - Jul 21 2013 : 05:34:42 Hello,
William's suggestion doesn't give back the wanted solution. But with William's idea with transparenty I will replace my CalcImagePalette: Using the MagicWand-function, setting the selection to transparenty and search from the middle of the image till finding the transparenty front will getting the outline. So it will work more faster.
I will report the result here.
Jens |
jenswahl |
Posted - Jul 21 2013 : 05:11:16 Hello,
thanks to William again and also to Prg. I also found that the "black" background isn't really black; there are some grey or white pixels included (if I show the image in 100% or more than I can see it) and so the inverted selected area is bigger as the page itself because the MagicWand doesn't include these pixels. Manually isn't possible - I have about 800 Books and about 400 Comics - to much. First I will try Willam's last suggestion and (if I doesn't get what I want) I will do the following:
var iColorCount: Integer;
iRGB, iRGB2: TRGB;
aRGB: array of TRGB;
begin iColorCount := ImageEnView1.Proc.CalcImageNumColors; SetLength(aRGB, iColorCount + 1); //but this needs a lot of time, on tests I got till 4..9 ... //...minutes for one image!!!: ImageEnView1.Proc.CalcImagePalette(aRGB, iColorCount); ... end; Maybe I resize the image before using CalcImagePalette to the half size to get a faster progress. Than I want to find a NOT used color clNotUsed in aRGB and fill the selected area (selected by MagicWand) with this color. From the middle of the image the pixels scanning till finding clNotUsed. So I want to get the outline of the page. This will need a long long time - I know it. But the most MUST be done automatically.
Jens
|
w2m |
Posted - Jul 19 2013 : 08:44:11 I finally found something that works. The problem with using selections is magicwand does not just select a rectangular area of the comic image and each image that you scan will not be the same which makes setting the tolerance difficult. Also it is likely that the magicwand is not truly a selected rectangle and probably has small "holes" included as part of the selection. The approach I used is similar to my previous suggestion except that it crops away the transparent area (formerly the gray border) and leaves the comic image itself which is what I think you are looking for.
The bitmap before processing is 716x598 and the bitmap after processing is 587x598.
When you are scanning the image the success of any processing regardless of how you do it depends on getting a relatively "clean" scan. My success over the years cleaning up a scanned image using magicwand has been problematic at best. I recommend you give up on magicwand and selections in general because it is difficult to get the selection correct because of differences in each scan.
I suspect that the reason that ievSrc.CopySelectionToIEBitmap(ievDest.IEBitmap) copies the whole photo rather than the selection is because a rectangular area of the comic is not really selected with your technique and there are small selections inside the comic image itself, so when you copy the selection to the IEBitmap it copies the entire image.
I think if you just select the comic manually with miSelect that CopySelectionToIEBitmap would work as expected. Update: I just tried a manually selected rectangle around the comic and CopySelectionToIEBitmap works correctly. In fact after processing the selection, the result is a bitmap with the same dimensions that the procedure shown below produces... 587x598.
So I recommend you try this again:
procedure TForm1.Button1Click(Sender: TObject);
var
iFilename: string;
begin
if OpenPictureDialog1.Execute then
begin
iFilename := OpenPictureDialog1.FileName;
if FileExists(iFilename) then
begin
Screen.Cursor := crHourGlass;
try
ImageEnVect1.Clear;
ImageEnVect1.LayersClear;
ImageEnVect1.RemoveAllObjects;
{ Load the image }
ImageEnVect1.IO.LoadFromFile(iFilename);
{ The comic dimensions are 716 x 598 }
ShowMessage('Dimensions: ' + IntToStr(ImageEnVect1.IEBitmap.Width) + ' x ' + IntToStr(ImageEnVect1.IEBitmap.Height));
{ Cast clWhite to the topleft of the image }
ImageEnVect1.Proc.CastColor(10, 10, TColor2TRGB(clWhite), 20);
{ Cast clWhite to the topright of the image }
ImageEnVect1.Proc.CastColor(ImageEnVect1.IEBitmap.Width - 10, 10, TColor2TRGB(clWhite),
20);
{ Make the white transparent }
ImageEnVect1.Proc.SetTransparentColors(TColor2TRGB(clWhite), TColor2TRGB(clWhite), 0);
ImageEnVect1.Update;
{ Crop the transparent border }
ImageEnVect1.Proc.CropTransparentBorder;
{ The comic dimensions are 587 x 598 }
ShowMessage('Dimensions: ' + IntToStr(ImageEnVect1.IEBitmap.Width) + ' x ' + IntToStr(ImageEnVect1.IEBitmap.Height));
finally
Screen.Cursor := crDefault;
end;
end;
end;
end; William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html |
w2m |
Posted - Jul 19 2013 : 07:00:56 I have not tried this, but there are two parameters procedure CopySelectionToIEBitmap(DestBitmap:TIEBitmap; FillBackground:boolean);
Description CopySelectionToIEBitmap copies the current selection to the specified bitmap. If FillBackground is true the background is filled using Background color, otherwise it is filled with image self.
Example Try setting the last parameter to true or false to see if it works: ImageEnView1.CopySelectionToIEBitmap( ImageEnView2.IEBitmap, False );
William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html |
Prg |
Posted - Jul 19 2013 : 03:09:23 You can use
ievSrc.Proc.AutoCrop(15,ievSrc.IEBitmap.Pixels[0,0]); 15 is good value but you can use other after tests. |
jenswahl |
Posted - Jul 19 2013 : 00:08:58 Hello,
Thank you to William, for your solution - but I get the same result like my example. The most images are photos (faster and better resolution as a scanner) I also tested: - CopyFromPolygon: I get the rectabngle of the page but only in white - CopySelectionToIEBitmap, SelCopyToClip: like my example - CopyToBitmapWithAlpha after the code by William: the complete photo only in white
The real question to me is the following: - ievSrc.SelectMagicWand(ptTmp.X, ptTmp.Y, iespReplace): works fine - ievSrc.InvertSelection: works fine, shows the wanted page - ievSrc.CopySelectionToIEBitmap(ievDest.IEBitmap): copies NOT the selection but the whole photo, why that?
Best regards
Jens |
w2m |
Posted - Jul 18 2013 : 08:07:57 If you are getting the image from a scanner, most scanners have the ability to do a preview that selects only the comic and not the entire bed of the scanner... that way the scanned bitmap is only the comic.
But, you can convert the black to white and then remove the white so only the comic is visible:
procedure TForm1.Button1Click(Sender: TObject);
var
iRGB: TRGB;
begin
{ Fill the area around the comic with white }
{ Cast clWhite to the topleft of the image }
ImageEnVect1.Proc.CastColor(10, 10, TColor2TRGB(clWhite), 15);
{ Cast clWhite to the topright of the image }
ImageEnVect1.Proc.CastColor(ImageEnVect1.IEBitmap.Width - 10, 10, TColor2TRGB(clWhite), 15);
iRGB := TColor2TRGB(clWhite);
{ Make the white transparent }
ImageEnVect1.Proc.SetTransparentColors(iRGB, iRGB, 0);
ImageEnVect1.Update;
ImageEnVect1.IO.SaveToFile('c:\Test\example.jpg');
end;  66.57 KB William Miller Adirondack Software & Graphics Email: w2m@frontiernet.net EBook: http://www.imageen.com/ebook/ Apprehend: http://www.frontiernet.net/~w2m/index.html |
|
|