1) How to support reading of image types without defining the Reader (JPEG, BMP, GIF, PNG...)
1) How to support reading of image types without defining the Reader (JPEG, BMP, GIF, PNG...)
All fpReadXXX functions register their reader in the global ImageHandlers of unit fpImage and TFPCustomImage makes use of that. So simply doing a TFPMemoryImage.LoadFromFile without any reader should work already.
However, it failed on one particular PNG file no matter I specify the Reader explicitly as PNG or not.The file might not be in PNG format in fact.
BTW, Has anyone tried to convert image to ASCII art before? To get the grey intensity, can I use back the same code, or use BGRABitmap?It does not really matter at this point. Though with BGRABitmap you could resample the image instead of getting individual pixels separated by some distance. The image may look better with resample.
However, it failed on one particular PNG file no matter I specify the Reader explicitly as PNG or not.The file might not be in PNG format in fact.
However, it failed on one particular PNG file no matter I specify the Reader explicitly as PNG or not.The file might not be in PNG format in fact.
It does not really matter at this point. Though with BGRABitmap you could resample the image instead of getting individual pixels separated by some distance. The image may look better with resample.
I was wondering about adding ASCII art features to BGRABitmap. Though I was thinking of trying something else: that the shape of the character would try to match the pixels it covers. For example to use "/" for a diagonal line etc.
If anyone of you remember Paint Shop Pro, there is a feature called "Increase color depth..." and "Decrease color depth...". This feature is called "color quantization" in Python programming.
Please find the attached PNG file which could not be opened with fcl-image, but can be opened using LazPaint (and of course, Windows Photo Editor)Trying to open this image with IrfanView I get the message that this is a jpg file with incorrect extension. The LCL TImage (which uses the fcl-image readers/writers) loads the image without any issues.
This is the error message:
C:\FPC>img2chr panda.png Error: Error while reading stream: Wrong image format
Please find the attached PNG file which could not be opened with fcl-image, but can be opened using LazPaint (and of course, Windows Photo Editor)Trying to open this image with IrfanView I get the message that this is a jpg file with incorrect extension.
This is the error message:
C:\FPC>img2chr panda.png Error: Error while reading stream: Wrong image format
Besides this, I have a feature suggestion for LazPaint. I am not sure about its usefulness though.It is possible to save a file in 256 colors, which makes color quantization. You can as well use the palette toolbar. For example generate 16 colors and then apply dithering with it. The image can still have all 24-bit colors but you can get the effect if you like.
If anyone of you remember Paint Shop Pro, there is a feature called "Increase color depth..." and "Decrease color depth...". This feature is called "color quantization" in Python programming.
As I have limited knowledge about mathematic calculation, I will leave it to you as to how to implement this feature (if you accept my suggestion).
Such as, 24-bit color reduced to 256 color or 16 color....etc.
Trying to open this image with IrfanView I get the message that this is a jpg file with incorrect extension. The LCL TImage (which uses the fcl-image readers/writers) loads the image without any issues.
If anyone of you remember Paint Shop Pro, there is a feature called "Increase color depth..." and "Decrease color depth...". This feature is called "color quantization" in Python programming.
Yes, I remember and I liked that feature.
IMHO, increasing color depth will be easy but decreasing is more tricky (maybe with different ways to calculate the average of the new color).
But I vote for it.
Besides this, I have a feature suggestion for LazPaint. I am not sure about its usefulness though.It is possible to save a file in 256 colors, which makes color quantization. You can as well use the palette toolbar. For example generate 16 colors and then apply dithering with it. The image can still have all 24-bit colors but you can get the effect if you like.
If anyone of you remember Paint Shop Pro, there is a feature called "Increase color depth..." and "Decrease color depth...". This feature is called "color quantization" in Python programming.
As I have limited knowledge about mathematic calculation, I will leave it to you as to how to implement this feature (if you accept my suggestion).
Such as, 24-bit color reduced to 256 color or 16 color....etc.
I guess that when you follow PascalDragon's idea with the ImageHandlers (i.e. loading the image without specifying a reader) fcl-image will open the file successfully even when it has a wrong extension.
Trying to open this image with IrfanView I get the message that this is a jpg file with incorrect extension. The LCL TImage (which uses the fcl-image readers/writers) loads the image without any issues.
After I renamed the panda.png to a new filename with .jpg extension, only then my program can interpret the image correctly...
I guess that when you follow PascalDragon's idea with the ImageHandlers (i.e. loading the image withoug specifying a reader) fcl-image will open the file successfully even when it has a wrong extension.
Trying to open this image with IrfanView I get the message that this is a jpg file with incorrect extension. The LCL TImage (which uses the fcl-image readers/writers) loads the image without any issues.
After I renamed the panda.png to a new filename with .jpg extension, only then my program can interpret the image correctly...
Ah, and it's even simpler than that, because there is another class function FindHandlerFromStream which does practically the same as my GetImageReaderClass function. My sample program now can be rewritten as:
procedure TForm1.Button2Click(Sender: TObject); var stream: TFileStream; readerClass: TFPCustomImageReaderClass; reader: TFPCustomImageReader; img: TFPMemoryImage; begin Label1.Caption := ''; stream := TFileStream.Create(FILE_NAME, fmOpenRead + fmShareDenyNone); try readerClass := TFPCustomImage.FindHandlerFromStream(stream).Reader; if Assigned(readerClass) then begin img := TFPMemoryImage.Create(0, 0); try reader := readerClass.Create; try img.LoadFromStream(stream, reader); finally reader.Free; end; Label1.Caption := Format('%d x %d', [img.Width, img.Height]); finally img.Free; end; end else ShowMessage('Unknown image type'); finally stream.Free; end; end;
Here is a working version of your program:
(snipped)
Please note that your original code tried to read the file twice, by ReadfromFile and then by ReadFromStream.
Yes, all of it is in the unit BGRAColorQuantization. There is a class TBGRAColorQuantizer that handles everything for you.It is possible to save a file in 256 colors, which makes color quantization. You can as well use the palette toolbar. For example generate 16 colors and then apply dithering with it. The image can still have all 24-bit colors but you can get the effect if you like.
Is there any programming API for these? It would be nice to use one instead of inventing my own.
I did not know that it can be done that way in LazPaint.
[...] because "wp" is too vague for me to attribute someone.
:)
Is there any programming API for these? It would be nice to use one instead of inventing my own.Yes, all of it is in the unit BGRAColorQuantization. There is a class TBGRAColorQuantizer that handles everything for you.
I did not know that it can be done that way in LazPaint.
[...] because "wp" is too vague for me to attribute someone.
:)
Says "anyone" :D
I wish to know your handle or email address (if not convenient, then that's okay) so that I can include it in my source code ("img2chr, developed by [me] and [@wp]") because "wp" is too vague for me to attribute someone.There is no reason to attribute me for this little piece of code. If you want you can acknowledge "contributions from the Lazarus forum" (mine was not the only one).
:)
procedure ReadImage; var color16, r, g, b:byte; readerClass: TFPCustomImageReaderClass; reader: TFPCustomImageReader; stream: TStream; begin if FileExists(ReadFile) then begin stream := TFileStream.Create(ReadFile, fmOpenRead + fmShareDenyNone); try stream.Position := 0; readerClass := TFPCustomImage.FindHandlerFromStream(stream).Reader; if Assigned(readerClass) then begin reader := readerClass.Create; try img.LoadFromStream(stream, reader); finally reader.Free; end; ...
Just for completeness: the line "stream.Position := 0" highlighted in my code snippet above is not necessary (the stream position is always zero after creation anyway) and can be omitted; it is a left-over of a previous version of the code.