How can I load a jpeg image from a buffer? - delphi

I want to store a jpeg image in a RC_DATA resource, but not a single image in one single RC_DATA. There are many things in that RC_DATA, all muxed together. At runtime I load that RC_DATA in a bufer and extract all the object, including this Jpeg. Now I have this image in a memory buffer and I need to load it in a TJpegImage or TBitmap. How can I do that ? I saw that those classes doesn't have some methods to achieve this...

Copy the JPEG bytes from your buffer into a TMemoryStream (or, use a TCustomMemoryStream to point directly at the JPEG bytes to avoid making a copy). And then you can pass that stream to TJPEGImage.LoadFromStream().

Related

How to store .raw or raw bytes of pictures to local disk documents folder without png or jpeg representation

I want to store the raw bytes of a captured picture using AVCaptureSession. But I have only seen examples of pngrepresentation and jpegrepresentation. I want to store the raw data bytes in local disk documents of phone so it can be reopened at other times and converted into a UIImage for post processing. Is there a way to do this?
for example:
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(pixelBuffer);
Can I store rawImageBytes in documents to open it later?
Sure you can. Create an NSData object containing your bytes and save that using one of the NSData file saving methods (e.g. writeToURL:atomically:.)
You'll need to know the number of bytes in your pixelBuffer though. It looks like you should use CVPixelBufferGetDataSize to get the number of bytes.

Comparing two JPEG images in iOS

I have images that I upload to a server using Amazon S3. I convert them to NSData, using UIImageJPEGRepresentation with 0.75f compression quality. Now I'd like to compare them and see if they are equal.
With PNG, it's easy, all I had to do is this:
if (UIImagePNGRepresentation(self.pictureImageView.image) isEqual:
UIImagePNGRepresentation(manageItemVC.pictureImage)]) {}
as stated here. And that would work, but now the images are JPEG, and the comparison isn't working (most likely due to compression), even if I use UIImageJPEGRepresentation.
self.pictureImageView.image is the image from the server that I've loaded into an UIImageView, and manageItemVC.pictureImage is an image that the user picked from the photo library.
Anyone know how to compare JPEG images?
You can check data's length of two image and compare it.
With my suggestion, i check if two data different about 10000 => two image different.

Convert TJpegImage to byte array

I am implementing webcam functionality in a client/server, and I am sending/receiving each frame over the socket as a JPEG. In order to do this, I am converting the JPEG into a byte array and then sending it. The server receives it as a byte array and converts it to a JPEG.
My question is how to convert the JPEG to a byte array (and vice versa) efficiently.
The way that I'm doing it now seems like it's probably not ideal. I'm currently creating a TMemoryStream, saving the JPEG into it, and then reading the stream into a byte array. Then on the server side, once it receives the array, I'm creating a TMemoryStream, writing the array into it, and then creating a TJpegImage and loading the stream into it.
It seems like my way requires a lot of steps, and memory allocations. Is there a better way?
There is no need for a conversion, you can directly save a jpeg image to a stream , transfer the stream, and load the jpeg from a stream.

Open an image using as little RAM as possible

I want to open some relative big files (jpg, gif, bmp) using as little RAM as possible.
Inside my program I need all open files converted to BMP so I can process them. However the conversion from JPG to BMP takes 27.1MB of RAM if I use the classic conversion code:
function ConvertJPG2BMP(FullFileName: string; BMP: TBitmap);
VAR JPG: TJpegImage;
begin
JPG:= TJpegImage.Create;
TRY
TRY
JPG.LoadFromFile(FullFileName);
BMP.Assign(JPG);
EXCEPT
END;
FINALLY
FreeAndNil(JPG);
end;
end;
because it uses two images (a jpeg that is transferred to a bitmap then).
--
However, if I use a TPicture to load the file, I use only 7.1MB of RAM. But in this case the TPicture.Bitmap is empty and I need a valid TBitmap object.
Is there any way to load images from disk while keeping the mem footprint small?
--
(Test file: 1.JPG 2.74MB 3264x1840 pix)
Back of the envelope calculation gives 6 mega pixels. Assuming 32 bit colour this takes you to 24MB.
You aren't going to do any better than your current code.
The memory usage does not come from the JPEG library, but in the way you use it.
If you convert a JPEG into a TBitmap, it will create a bitmap resource, then uncompress the JPEG into the bitmap memory buffer.
You can paint directly from the JPEG content into the screen. Depending on the JPEG implementation, it will use (or not) a temporary TBitmap.
You are not tied to the JPEG unit supplied by Borland.
For instance, you may try calling directly the StretchDIBits() windows API from the uncompressed memory buffer, as such (this code is extracted from our SSE JPEG decoder):
procedure TJpegDecode.DrawTo(Canvas: TCanvas; X, Y: integer);
var BMI: TBitmapInfo;
begin
if #self=nil then
exit;
ToBMI(BMI);
StretchDIBits(Canvas.Handle,X,Y,width,height,0,0,width,height,pRGB,
BMI,DIB_RGB_COLORS,SrcCopy);
end;
Creating a huge bitmap is sometimes not possible (at least under Windows XP), because it uses shared GDI resources, whereas using plain RAM and StretchDIBits will always work, even for huge content. You can create a memory mapped file to handle the binary content, but just allocating the memory at once would suffice (and Windows will use hard drive only if short of RAM). With today's PCs, you should have enough RAM available even for big pictures. (17 MB is not a big deal, even for your 3264x1840 pix).
Then, from this global uncompressed memory buffer containing raw pixel triplets, you can use
a smaller bitmap corresponding to a region of the picture, then work on the region using StretchDIBits(aBitmap.Handle,.... It will use less GDI resource.
You could also rely for instance on GDI+ drawing, which will draw it without any temporary bitmap. See e.g. this OpenSource unit. From our testing, it's very fast and can be used without any TBitmap. You could also ask only for a region of the whole picture, and draw it using GDI+ on your bitmap canvas: this will use less RAM. And your exe will be a bit smaller than the default JPEG unit. And you'll be able to display and save not only JPEG, but GIF and TIFF formats.
If you want to minimize even further the memory usage, you'll have to call directly the JPEG library, at lowest-level. It's able to uncompress only a region of the JPEG. So you would be able to minimize used RAM. You may try using the IJL library with Delphi, a bit old, but still working.

File Format Conversion to TIFF. Some issues?

I'm having a proprietary image format SNG( a proprietary format) which is having a countinous array of Image data along with Image meta information in seperate HDR file.
Now I need to convert this SNG format to a Standard TIFF 6.0 Format. So I studied the TIFF format i.e. about its Header, Image File Directories( IFD's) and Stripped Image Data.
Now I have few concerns about this conversion. Please assist me.
SNG Continous Data vs TIFF Stripped Data: Should I convert SNG Data to TIFF as a continous data in one Strip( data load/edit time problem?) OR make logical StripOffsets of the SNG Image data.
SNG Data Header uses only necessary Meta Information, thus while converting the SNG to TIFF, some information can’t be retrieved such as NewSubFileType, Software Tag etc.
So this raises a concern that after conversion whether any missing directory information such as NewSubFileType, Software Tag etc is necessary and sufficient condition for TIFF File.
Encoding of each pixel component of RGB Sample in SNG data:
Here each SNG Image Data Strip per Pixel component is encoded as:
Out^[i] := round( LineBuffer^[i * 3] * **0.072169** + LineBuffer^[i * 3 + 1] * **0.715160** + LineBuffer^[i * 3+ 2]* **0.212671**);
Only way I deduce from it is that each Pixel is represented with 3 RGB component and some coefficient is multiplied with each component to make the SNG Viewer work RGB color information of SNG Image Data. (Developer who earlier work on this left, now i am following the trace :))
Thus while converting this to TIFF, the decoding the same needs to be done. This raises a concern that the how RBG information in TIFF is produced, or better do we need this information?.
Please assist...
Are you able to load this into a standard windows bitmap handle? If so, there are probably a bunch of free and commercial libraries for saving it as TIFF.
The standard for TIFF is libtiff -- it's a C library. Here's a version for Delphi made by an expert in the TIFF format:
http://www.awaresystems.be/imaging/tiff/delphi.html
There seems to be a lot of choices.
I think the approach of
Loading your format into an in-memory standard bitmap (which you need to do to show it, right?)
Using a pre-existing TIFF encoding library to save as TIFF
Will be a lot easier than trying to do a direct format-to-format conversion. The only reasons I wouldn't do it this way are:
The bitmap is too big to keep in memory
The original format is lossy and I will lose more quality in the re-encoding -- but you'd have to be saving in a standard lossy format (JPEG) to save quality.
Disclaimer: I work for Atalasoft.
We make .NET imaging codecs (including TIFF) -- that are a lot easier to use than LibTiff -- you can call them in Delphi through COM. We can convert standard windows bitmaps to TIFF or PDF (or other formats) with a couple of lines of code.
One approach, if you have a Windows application which handles and can print this format, would be to let it do the work for you, and call it to print the file to one of the many available 'printer drivers' which support direct output to TIFF.

Resources