Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Open a jpg, mod jpg, close and save jpg 2

Status
Not open for further replies.

cfsjohn

Programmer
Sep 1, 2016
64
US
I have a Topaz signature pad. It captures the customer's signature at the end of a sale. It can save the signature to a string (it is a very long string), a sig file which I guess would be Topaz proprietary, bmp, jpg, png, tiff and wmf and emf. I have it saving the signatures as an jpg image file. It works. I can print the jpg on the receipt (a VFP9 report). My problem is the signature is very small. I can't find a way via Topaz commands to make the signature larger. The jpg file contains a lot of whitespace aroung the actual signature. If I could somehow (from VFP), open the jpg, find the 1st instance of a black dot in the jpg (that would be where the actual signature starts), maybe I could automatically crop the jpg and resave it ending up with an image that ONLY contains the actual signature (so leaving out all the whitespace around the actual signature). I've looked at using the VFP GDIPlus library and maybe the GDIPlus X library on github (i really don't understand how to download that library from github).

Can anyone tell me the easiest way to get from point a to b on this?

Thanks,
John
 
 https://files.engineering.com/getfile.aspx?folder=af0e6a10-6d0f-4327-bc8a-1069e3407836&file=00598934.jpg
Thanks, now it works.

The savings are low, as I already saw myself. You get more from changing to 1bpp monochrome than from resizing to 80% image dimensions. But most important the cropping works, so that pixel format conversion can also be done separately.

Chriss
 
If the high resolution isn't important, I could make an option to decrease the DPI so it stores the same size, but with fewer pixels. But I really don't see how size would be an issue. It looks like its 10s of KB per signature anyway.

--
Rick C. Hodgin
 
No, sorry that I was perhaps not clear enough. Your code crops and keeps the pixelformat. For cfsjohns case it would be best to convert to monochrome.

I saw gdiplusx has a GetMonochrome() method. You can get a 4KB GIF from the Hook signature even without cropping at all, just changing the pixelformat, not dpi, just converting from the 8bpp indexed JPG the device saves to 1bppindexed with black/white palette:
Code:
Do system.app

loBitmap = _screen.system.Drawing.Bitmap.FromFile("00598934.jpg")
loMono = loBitmap.GetMonochrome()
loMono.Save("00598934converted.gif")
I attached the result of that.

Chriss
 
 https://files.engineering.com/getfile.aspx?folder=0383bea6-b95c-4fcc-a6d9-ff8d1d69a896&file=00598934converted.gif
I can expose any ability that's available and/or required. If you save as a .TIF file does that save as monochrome?

Also, I think it should have some kind of softening algorithm applied before converted to monochrome, so it would lose dithering / speckles from pixels that are within some color range. I think the threshold value like what GIMP uses to select an area by color would again work for that.

--
Rick C. Hodgin
 
If I take the quality of the original images for granted by the "Hook" example, then there are no speckles in the images that would cause single black pixels where the original has just a grey pixel artifact. In short, that conversion is working very well and the signature quality actually is better than the original. Just view it zoomed large.

As the signatures finally are printed on thermo paper, I think, the quality aspect is less of a concern, I just point out that converion to monochromes has a better effect on the file size than lowering the resolution and sticking to the greyscale palette. Maybe, Rick, I should point out that the major concern of cropping has become just a secondary concern as sending the image to the back of the report also solved the initial problem. Indeed this also has an advantage of a fixed size and position of the image in the report.

From a post of May, 30th:
cfsjohn said:
As I will have hundreds of these image files generated daily, I believe it would be a good idea to do whatever I can that would reduce the size of the files

So that's become the major concern: File size. I just repeatedly point out that while your DLL now crops fine, it is besides the point, if its result files are not also shortening the files as much as they could. And I think it would be a shame to not use your perfect and simple cropping, Rick.

In the end cfsjohn will have to decide what's important and best for him, I'm just making my recommendations. I think I'll just stop here and leave it up to you both to finish this thread, have a good time, Rick! And all the best for your VFP clone project, too.

Chriss
 
Just one more suggestion to let the image.dll be usable for the most general case: Offer a method to change the color mode of the image as a functionality separate to cropping. If I understand you correctly this class is part of your VFP clone project. It's nothing VFP itself offers with its image control, it just displays an image as is and offers no manipulation other than is done by stretch to fit, which is certainly the reason your dll has the resize functionality. It would add to the capabilities to offer color mode change, but there's no harm to compatibility whhen your clone offers additional functionalities.

The monochrome preprocessing step is easily done with GDIPlusX, just a 4-liner as I showed, but you know cfsjohn has trouble getting GDIPlusX to work for him. Besides cropping is neither a feature of GDI+ nor GDIPlusX nor VFP image control, too.

By the way, I recently came across a bug (or is it by design?) of the VFP image control stretch. If you design a PNG image with a vertical color gradient from a color to transparency and make it 1 pixel wide only as you can stretch it to any width needed by the image control, VFP will cause a horizontal color gradient by stretching the width. The bug could be how GDI+ resizes, but that is annoying.

Chriss
 
If you look at bitmap1.h beginning at line 531, you can see the functions that are currently available to be exposed. I don't have any that will move it to a monochrome bitmap, but that shouldn't be too hard to add.

See if there are any other functions you'd like to see exposed. I've been extending this library for use with my upcoming x86 assembly tutorial as well, so I have added some text drawing functions, and layering functions which allow things to be changed on any layer, then merged into the visible layer for rendering. It allows special effects to be used, animations, layers to be turned on and off. Should make a nice addition for future tutorials as well.

--
Rick C. Hodgin
 
I added the conversion to mono. Something's not right though, the last 26 bytes of the file are showing all black. I don't know what's causing it yet. Will sort it out when I have time.

--
Rick C. Hodgin
 
Thinking to use the DLL in the context of the image control the ones making sense would be
iBmp_grayscale
iiBmp_setPixel
iBmp_extractColorAtPoint
and the drawing functions for lines and text.

Get/set pixel is not that useful as slow as VFP is, but that could change with how you compile VFrP code.

If I think of what I'd use now in VFP it's either GDIPlusX to actually work on images with all GDI+ flat API functions available. Or workaraound using what VFP has itself. I'd not introduce GDIPlusX for simple purposes like adding text on an image, because that can also be done by a label control on top with background transparent instead of GDI+ text drawing on the image bitmap itself. And lines and shapes can be done with shape controls, too, even when that's a bit more tedious.

It would be nice to have support for vector graphic formats, if I could only pick one, SVG. But that would be more of a topic of bringing up a webbrowser control that could host a Chrome or FireFox render engine instead of IE, I'd not bother if I can also use the Edge engine. With any of them SVG is just one of so many more features made available by a webbrowser.


Chriss
 
Here are the functions I'm adding. I have the ones at the top completed, the ones at the bottom I still need to code:

Code:
* These have been coded
DECLARE INTEGER bmp_grayscale               IN image.dll INTEGER nHandle, SINGLE fAlpha
DECLARE INTEGER bmp_set_pixel               IN image.dll INTEGER nHandle, INTEGER nX, INTEGER nY, INTEGER nRgb
DECLARE INTEGER bmp_get_pixel               IN image.dll INTEGER nHandle, INTEGER nX, INTEGER nY
DECLARE INTEGER bmp_colorize                IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER colorTemplate, SINGLE fAlpha
DECLARE INTEGER bmp_swap_colors             IN image.dll INTEGER nHandle, INTEGER colorOld, INTEGER colorNew
DECLARE INTEGER bmp_wavy_line               IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER colorLine
DECLARE INTEGER bmp_dapple                  IN image.dll INTEGER nHandle, INTEGER nHandleDapple, SINGLE fInfluence
DECLARE INTEGER bmp_draw_font               IN image.dll INTEGER nHandle, STRING cFontName, INTEGER nPointSize, INTEGER lBold, INTEGER lItalic, INTEGER lUnderline, INTEGER lStrikethru, STRING cText, INTEGER nX, INTEGER nY, INTEGER textColor
DECLARE INTEGER bmp_draw_font_fixed_point   IN image.dll INTEGER nHandle, INTEGER fontPixelsX, INTEGER fontPixelsY, STRING cText, INTEGER nTextLength, INTEGER nX, INTEGER nY, INTEGER foreColor, INTEGER backColor
DECLARE INTEGER bmp_draw_bullet             IN image.dll INTEGER nHandle, INTEGER nX, INTEGER nY, INTEGER colorBullet
* The rectangles are pixel coordinates from upper-left X,Y (nULX,nULY), to lower-right X,Y (nLRX,nLRY), the clipping rectangle
DECLARE INTEGER bmp_fill_rect               IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER nColorNW, INTEGER nColorNE, INTEGER nColorSW, INTEGER nColorSE, INTEGER lUseGradient
DECLARE INTEGER bmp_frame_rect              IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER nColorNW, INTEGER nColorNE, INTEGER nColorSW, INTEGER nColorSE, INTEGER lUseGradient
DECLARE INTEGER bmp_colorize_rect           IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER nColorNW, INTEGER nColorNE, INTEGER nColorSW, INTEGER nColorSE, INTEGER lUseGradient, SINGLE fAlpha
DECLARE INTEGER bmp_frame_in_nine_parts     IN image.dll INTEGER nHandle, INTEGER nULX, INTEGER nULY, INTEGER nLRX, INTEGER nLRY, INTEGER nHandleSrc
DECLARE INTEGER bmp_draw_line               IN image.dll INTEGER nHandle, INTEGER nX1, INTEGER nY1, INTEGER nX2, INTEGER nY2, INTEGER color
DECLARE INTEGER bmp_draw_quad               IN image.dll INTEGER nHandle, INTEGER nX1, INTEGER nY1, INTEGER nX2, INTEGER nY2, INTEGER nWidth, INTEGER lDrawEnds, INTEGER colorLine

* Still need to code these
DECLARE INTEGER bmp_colorize_line           IN image.dll INTEGER nHandle, INTEGER nX1, INTEGER nY1, INTEGER nX2, INTEGER nY2, INTEGER colorLine, SINGLE fAlpha
DECLARE INTEGER bmp_draw_line_gradient      IN image.dll INTEGER nHandle, INTEGER nX1, INTEGER nY1, INTEGER nX2, INTEGER nY2, SINGLE fRed, SINGLE fGrn, SINGLE fBlu, SINGLE fRedInc, SINGLE fGrnInc, SINGLE fBluInc
DECLARE INTEGER bmp_colorize_line_gradient  IN image.dll INTEGER nHandle, INTEGER nX1, INTEGER nY1, INTEGER nX2, INTEGER nY2, SINGLE fRed, SINGLE fGrn, SINGLE fBlu, SINGLE fRedInc, SINGLE fGrnInc, SINGLE fBluInc, SINGLE fAlpha

--
Rick C. Hodgin
 
I believe I have most everything tested here. Take a look at it and report any issues.

If you uncomment the various portions of code you can see how those parts work. I used image.prg for the class definition and for my algorithm testing. It can be extracted out to your apps however's needed. Will push the changes to GitHub this weekend if there are no bugs.

The convert to mono still isn't working properly, but it's close. I'll figure that out at a later date. I've been working on a scalable server app the past couple of weeks. It's taken most of my time.

Please see attached for image.zip, which contains image.prg and image.dll plus the source images used for some of the testing.

--
Rick C. Hodgin
 
 https://files.engineering.com/getfile.aspx?folder=b1a31d75-6f35-40b2-bbe4-635076d5d34d&file=image.zip
Updated version. I've added alpha channels on some of the functions, and combined a few.

I'm going to begin using a version of this library for my x86 assembly tutorial.

See attached. See EnsignRho on GitHub for the source code.

--
Rick C. Hodgin
 
 https://files.engineering.com/getfile.aspx?folder=377013ba-2b2c-47ff-992d-a0d60ed2bd64&file=image_2023_06_22.zip
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top