How to add gif and tiff support to TJvDBImage? - delphi

TJvDBImage is a good component that support several picture formats. In JvJVCLUtils, it mentioned that the supported format can be expanded by RegisterGraphicSignature procedure. In the comment it mentioned :
WHAT IT IS:
These are helper functions to register graphic formats than can
later be recognized from a stream, thus allowing to rely on the actual
content of a file rather than from its filename extension.
This is used in TJvDBImage and TJvImage.
IMAGE FORMATS:
The implementation is simple: Just register image signatures with
RegisterGraphicSignature procedure and the methods takes care
of the correct instantiation of the TGraphic object. The signatures
register at unit's initialization are: BMP, WMF, EMF, ICO, JPG.
If you got some other image library (such as GIF, PCX, TIFF, ANI or PNG),
just register the signature:
RegisterGraphicSignature(<string value>, <offset>, <class>)
or
RegisterGraphicSignature([<byte values>], <offset>, <class>)
This means:
When <string value> (or byte values) found at <offset> the graphic
class to use is <class>
For example (actual code of the initialization section):
RegisterGraphicSignature([$D7, $CD], 0, TMetaFile); // WMF
RegisterGraphicSignature([1, 0], 0, TMetaFile); // EMF
RegisterGraphicSignature('JFIF', 6, TJPEGImage);
You can also unregister signature. IF you want use TGIFImage instead of
TJvGIFImage, you can unregister with:
UnregisterGraphicSignature('GIF', 0);
or just
UnregisterGraphicSignature(TJvGIFImage); // must add JvGIF unit in uses clause
then:
RegisterGraphicSignature('GIF', 0, TGIFImage); // must add GIFImage to uses clause
I follow the instruction and Added GIFImage in the uses clause at that unit. Also, in procedure GraphicSignaturesNeeded I added :
RegisterGraphicSignature('GIF', 0, TGIFImage);
RegisterGraphicSignature([$4D, $4d, 0, $2A], 0, TWICImage); // TIFF
RegisterGraphicSignature([$49, $49, $2A, 0], 0, TWICImage); // TIFF
The TIFF info is based on
Tip: detecting graphic formats
Then I used the makemodified.bat to re-compile JVCL.
Before the change, loading image to the TJvDBImage will load the file and give endless error of "bitmap image not valid". After change, it refuse to load the file and give the same error for 1 time.
If I load GIF / TIFF image to the field using other tools, when displaying , it give endless error mentioned above. If I load the field content using the above link functions, it can display in a TImage perfectly.
So, what have I missed or doing wrong?
Thank you!

Related

How to create animated GIF files, from bitmaps, that are compatible with all media-players?

I am trying to create an animated GIF file from 8 bit-pixel bitmaps, and save it in a format compatible with Windows Media Player and VideoLan VLC, using Anders Melander's GIFImage.Pas library and Graphics system library.
The result, for now, is a file that contains no errors, but is not animated. How can I save a series of 8-bit-pixel TBitMap images to an animated GIF file?
Here is the test library:
Unit Prova;
(* This GIF saving test make a GIF file that can't be opened with
Windows Media Player nor VideoLan VLC,
because it seems to has some errors *)
Interface
Uses Graphics,GIFImage; (* Copyright: (c) 1997-99 Anders Melander *)
Procedure SaveBitmaps(Picture1,Picture2,Picture3:TBitMap
(* Same graphics resolution, 8 Bit Pixel + Palette *);
GIFFN:String);
Implementation
Procedure SaveBitmaps(Picture1,Picture2,Picture3:TBitMap
(* Same graphics resolution, 8 Bit Pixel + Palette *);
GIFFN:String);
Var GIFImg:TGIFImage;
Begin
GIFImg:=TGIFImage.Create;
GIFImg.AnimationSpeed:=30;
GIFImg.Transparent:=False;
GIFImg.Animate:=True;
GIFImg.Width:=Picture1.Width;
GIFImg.Height:=Picture1.Height;
Try
GIFImg.Add(Picture1);
GIFImg.Add(Picture2);
GIFImg.Add(Picture3);
GifImg.OptimizeColorMap;
GifImg.Optimize([ooMerge,ooCrop],rmNone,dmNearest,0);
GIFImg.SaveToFile(GifFN);
Finally
GIFImg.Destroy;
End;
End;
End.
I've created a .GIF animated file named "Treno.Gif" that contains 320 frames at 8 bit-pixel, 320 pixel width and 200 pixel width, with this method, and i've tested it on the web at:
gif debugger world's simplest gif tool
The error that occours is:
Error: TypeError: Cannot read properties of null (reading 'delay')
The file is:
Treno.Gif
It was created with a tool, named Anim32, which I am still developing;
you can find it at:
Anim32 V.093
and help me solve any problems with the GIF format.
WARNING: I Want to use GIFImage.pas unit, made by Anders Melander, Filip Larsen and Reinier Sterkenburg and
not GIFImg that it is included in Delphi 2007 package!
The solution of Andreas Rejbrand:
Delphi TGIFImage animation issue with some GIF viewers
it is certainly valid, but, as I wrote, I need to use gifimage.pas and not gifimg.

Creating an RGB CVOpenGLESTexture in iOS

I am trying to create a 3-channel CVOpenGLESTexture in iOS.
I can successfully create a single-channel texture by specifying kCVPixelFormatType_OneComponent8 in CVPixelBufferCreate() and GL_LUMINANCE for both format and internalFormat in CVOpenGLESTextureCacheCreateTextureFromImage().
Similarly, I can successfully create a 4-channel RGBA texture by specifying kCVPixelFormatType_32BGRA in CVPixelBufferCreate() and GL_RGBA for both format and internalFormat in CVOpenGLESTextureCacheCreateTextureFromImage().
I need to create 3-channel, 24-bit, RGB (or BGR) texture with accessible pixels.
I cannot seem to find the correct parameters (or combination thereof) to CVPixelBufferCreate() and CVOpenGLESTextureCacheCreateTextureFromImage() that will not cause either of them to fail.
Additional Info
The supported FOURCC format types reported by CVPixelFormatDescriptionArrayCreateWithAllPixelFormatTypes() on my device:
32, 24, 16, L565, 5551, L555, 2vuy, 2vuf, yuvs, yuvf, 40, L008, L010, 2C08, r408, v408, y408, y416, BGRA, b64a, b48r, b32a, b16g, R10k, v308, v216, v210, v410, r4fl, grb4, rgg4, bgg4, gbr4, 420v, 420f, 411v, 411f, 422v, 422f, 444v, 444f, y420, f420, a2vy, L00h, L00f, 2C0h, 2C0f, RGhA, RGfA, w30r, w40a, w40m, x420, x422, x444, x44p, xf20, xf22, xf44, xf4p, x22p, xf2p, b3a8.
Interestingly, some of these values are not defined in CVPixelBuffer.h.
When I pass kCVPixelFormatType_24RGB (24 == 0x18) to CVPixelBufferCreate() it succeeds, but then CVOpenGLESTextureCacheCreateTextureFromImage() fails with error code -6683:kCVReturnPixelBufferNotOpenGLCompatible.
Answering myself, though I will be happy to be proved wrong and shown how to do this.
As I show here (answering myself yet again) it is possible to list all the fourCC buffer formats supported on the device, and a bunch of format attributes associated with each such fourCC format.
The flags pertinent to this question are:
kCVPixelFormatOpenGLESCompatibility
kCVPixelFormatContainsAlpha : Should be false;
kCVPixelFormatContainsRGB : Note: supported only from __IPHONE_8_0, but not strictly necessary;
Using the debugger, I found another helpful key: CFSTR("IOSurfaceOpenGLESTextureCompatibility") which will verify that the OpenGL ES texture supports direct pixel access with no need for (the slower) glReadPixels() and glTexImage2D().
Unfortunately, using these flags, it seems that there is currently no such RGB/BGR supported format.

Opencv - create png image

As part of my project I wanted to send stream of images using websockets from embedded machine to client application and display them in img tag to achieve streaming.
Firstly I tried to send raw RGB data (752*480*3 - something about 1MB) but in the end I got some problems with encoding image to png in javascript based on my RGB image so I wanted to try to encode my data to PNG firstly and then sent it using websockets.
The thing is, I am having some problems with encoding my data to PNG using OpenCV library that is already used in the project.
Firstly, some code:
websocketBrokerStructure.matrix = cvEncodeImage(0, websocketBrokerStructure.bgrImageToSend, 0);
websocketBrokerStructure.imageDataLeft = websocketBrokerStructure.matrix->rows * websocketBrokerStructure.matrix->cols * websocketBrokerStructure.matrix->step;
websocketBrokerStructure.imageDataSent = 0;
but I am getting strange error during execution of the second line:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid
and I am a bit confused why I am getting this error from my code.
Also I am wondering if I understand it right: after invoking cvEncodeImage (where bgrImage is IplImage* with 3 channels - BGR) I just need to iterate through data member of my CvMatto get all of the png encoded data?
The cvEncodeImage function takes as its first parameter the extension of the image you want to encode. You are passing 0, which is the same thing as NULL. That's why you are getting the message NULL not valid.
You should probably use this:
websocketBrokerStructure.matrix = cvEncodeImage(".png", websocketBrokerStructure.bgrImageToSend, 0);
You can check out the documentation of cvEncodeImage here.
You can check out some examples of cvEncodeImage, or its C++ brother imencode here: encode_decode_test.cpp. They also show some parameters you can pass to cvEncodeImage in case you want to adjust them.

TBitmap->LoadFromStream failed with Win XP

I'm using C++ Builder XE3 to develop a graph editor. All of the editing and drawing capabilities are made in a DLL that is loaded by the end user applications.
To store information about the available graph objects I use a SQLite database. That database contains BMP icons that are loaded into a TImageList at run-time.
Everything works fine with Win-7, Win-8 and Win-vista but with Win-XP a "Floating point division by 0" occurs when loading the bitmap. I use a temporary memory stream to load the blob from the database and then load it into a temporary TBitmap which is used to add the new icon into the final TImageList.
Here is the function used to do so...
void TIcons::AddMaskedBitmap( TImageList *ptImgList, unsigned char *pucIcon, unsigned int uiSize )
{
TMemoryStream *ptMemStream;
// Use a memory stream
ptMemStream = new TMemoryStream();
ptMemStream->Write( pucIcon, uiSize );
ptMemStream->Position = 0;//Seek( ( int )0, ( unsigned short )soBeginning );
// Load using the cached bmp object
m_ptBmp->Transparent = true;
#warning "floatting point division by 0 error with WinXP"
m_ptBmp->LoadFromStream( ptMemStream ); // floatting point division by 0 error with WinXP
// m_ptBmp->LoadFromFile( ".\\d.bmp" ); // works
// Create a mask
m_ptBmpMask->Assign( m_ptBmp );
m_ptBmpMask->Canvas->Brush->Color = m_ptBmp->TransparentColor;
m_ptBmpMask->Monochrome = true;
// Add it to the list
ptImgList->Add( m_ptBmp, m_ptBmpMask );
// Free mem
m_ptBmp->FreeImage();
m_ptBmpMask->FreeImage();
delete ptMemStream;
}
I've traced the TBitmap::LoadFromStream function and the exception occurs in the CreateDIBSection function.
To make sure the loaded bitmap files are saved using the right encoding I've tried to load them using the TBitmap::LoadFromFile function and it works fine, so I think there's something wrong with the TBitmap::LoadFromStream function but I can't figure out what !
If anyone has an idea...
Thanks.
LoadFromFile is implemented by creating a file stream, and passing that to LoadFromStream. This, if the contents of your memory stream are the same as the contents of the file, then the call to LoadFromStream will succeed.
Thus the only sane conclusion is that the contents of the memory stream are invalid in some way.
The bitmap stored into the database is encoded using the BITMAPV4HEADER structure which is supposed to be supported since Win95/NT4 but there's something wrong.
It works fine if I encode the bitmap using the BITMAPINFOHEADER structure which is an older version of bitmap encoding which does not contain color space information.
Just found out a solution that works for me.
My problem was that software that was developed on Win7, when running on XP was throwing the division by 0 error when loading one of my BMPs.
It turns out that the problematic BMP was saved using Win7 Paint (other BMPs that were ok were saved from Gimp).
All I needed to do to fix it was to open this BMP on XP Paint and save it from there.

Is there a way to force Magick++ to skip its cache when writing modified PixelPackets?

I have written a program that relies on Magick++ simply for importing and exporting of a wide variety of image formats. It uses Image.getPixels() to get a PixelPacket, does a lot of matrix transformations, then calls Image.syncPixels() before writing a new image. The general approach is the same as the example shown in Magick++'s documentation. More or less, the relevant code is:
Magick::Image image("image01.bmp");
image.modifyImage();
Magick::PixelPacket *imagePixels = image.getPixels(0, 0, 10, 10);
// Matrix manipulation occurs here.
// All actual changes to the PixelPacket direct changes to pixels like so:
imagePixels[i].red = 4; // or any other integer
// finally, after matrix manipulation is done
image.syncPixels();
image.write("image01_transformed.bmp");
When I run the above code, the new image file ("image01_transformed.bmp" in this example) ends up being the same as the original. However, if I write it to a different format, such as "image01_transformed.ppm", I get the correct result: a modified image. I assume this is due to a cached version of the format-encoded image, and that Magick++ is for some reason not aware that the image is actually changed and therefore the cache is out of date. I tested this idea by adding image.blur(1.0, 0.1); immediately before image.syncPixels();, and forcing this inconsequential change did indeed result in the correct result for same-format images.
Is there a way to force Magick++ to realize that the cache is out-of-date? Am I using getPixels() and syncPixels() incorrectly in the first place? Thanks!

Resources