I would really appreciate if somebody gives me a key to this problem...
I want to convert colored JPEG image to grayscale. I do following:
FJpg.GrayScale := True;
FJpg.LoadFromStream( FJpgStream ); // stream contains valid colored JPEG
FJpg.Compress;
FJpg.SaveToStream( FJpgMonoStream);
Does not work! FJpgMonoStream still contains colored image.
I found the following combination works:
FJpg.GrayScale := True;
FJpg.LoadFromStream( FJpgStream ); // stream contains valid colored JPEG
FBmp.Assign( FJpg );
FJpg.Assign( FBmp );
FJpg.SaveToStream( FJpgMonoStream);
But it is quite ugly, and I don't like to have additional TBitmap object.
Is there way to perform Color->Grayscale transition using the only
TJpegImage object? Help&docs are quite unclear in this subject and ther are
no sources of TJpegImage. TeamB, do you know how the beast wroks?
Thanks in advance
Sergei Soudakov
Well, I didn't know there _was_ a Grayscale property. When I saw there
was one I tried to guess how to use it to convert a jpg to grayscale, but it
didn't work the way I thought. So I looked at the docs, and actually what it
says in the docs seems perfectly clear to me: they say the Grayscale property
affects the "output", which presumably means it doesn't affect the jpg data
itself.
Surely it's theoretically possible to take a jpg and extract just
the luminosity part, saving that to a new jpeg without any decompression
and recompression. May not be possible with TJPEGImage - if you're resigned
to some decompression I suspect the above is fairly efficient, in particular
it seems probably much more efficient than assigning the colored jpg to a
bitmap, converting it to grayscale and saving as another jpg: if the docs
are telling the truth it will be much better beause the color part in the
original never gets decompressed.
--
David Ullrich
sig.txt still not found
Thank you very much for the answer.
Assigning data from one TJpegImage object (colored) to another (with
GrayScale set to True) does not work also. Accordingly to docs, in such a
case, all instances of TJpegImage share the same TJpegData object
(containing real Jpeg data source).
I found a way to get monochrome using the only instance of TJpegImage object
FJpg.LoadFromStream( FJpgStream );
FJpg.GrayScale := True;
FJpg.Performance := jpBestSpeed;
FJpg.DIBNeeded;
FJpg.Compress;
FJpg.SaveToStream( FJpgMonoStream );
If you comment out the line with "DIBNeeded" conversion does not occur. (But
in this case what Compress does? doc says that Compress call forces
compression, so it works always (?))
This way is the same slow as in previous example with assigning to bitmap .
"Slow" means, I can process 15-16 images/sec if mono-conversion does not
work (DIBNeede is commented out) and only 4 images/sec if real conversion
occurs. It turns out, getting plain bitmap from JPEG (decompressing) is much
slower than compressing (or my logic is wrong).
I'm really discouraged by this speed. World is not perfect... :-(
Sergei Soudakov
Davie
I believe the docs state that COMPRESS forces a compression to take place, but
there NEEDS to be something to compress FROM. This FROM is a dib bmp memory
area. In order to get this DIB is to call DIBNEEDED, does that make more sense
now?
Davie
>I believe the docs state that COMPRESS forces a compression to take place,
but
>there NEEDS to be something to compress FROM. This FROM is a dib bmp
>memory area. In order to get this DIB is to call DIBNEEDED, does that make
>more sense now?
Conclusion is:
a) Loading JPEG from stream does not cause internal DIB update.
b) No way to check does internal DIB currently present or not.
c) No way to check does internal JPEG data correspond to DIB image.
d) The only way to understand how any Delphi class works is to test it
intensively in practice, documentation is sometimes too weak.
Must do everything manually.. :-(
Thank you for productive discussion.
Sergei Soudakov.
Excellent. You say you're disappointed at how slow this is - I
filed it under "FastGrayscaleJPEG".
> If you comment out the line with "DIBNeeded" conversion does not occur. (But
> in this case what Compress does? doc says that Compress call forces
> compression, so it works always (?))
I _suspect_ that leaving out the Compress would not change anything.
> This way is the same slow as in previous example with assigning to bitmap .
My guess was that the previous method was about as fast as it was
going to get using TJPEGImage. As a rule these things are fairly smart about
not decoding, etc, until needed, not copying data when copying a reference
would suffice, etc, so I suspect that the DIBNeeded is doing more or less
the same amount of work as the assignment to the bitmap did.
> "Slow" means, I can process 15-16 images/sec if mono-conversion does not
> work (DIBNeede is commented out) and only 4 images/sec if real conversion
> occurs. It turns out, getting plain bitmap from JPEG (decompressing) is much
> slower than compressing (or my logic is wrong).
This is exactly as I suggested yeaterday: if you get a plain bitmap
from the JPEG you're decompressing the color channels as well as the
luminosity - here you're only decompressing the luminosity, much faster.
Must be a way to simply copy the compressed luminosity data without
ever decompressing it(???), but possibly not with TJPEGImage(???).
> I'm really discouraged by this speed. World is not perfect... :-(
Seems pretty fast to me. (Of course the numbers you give don't
mean much since you don't say anything about the size of the images.)
> Sergei Soudakov
> Seems pretty fast to me. (Of course the numbers you give don't
>mean much since you don't say anything about the size of the images.)
These numbers were mentioned just for comparison between Jpeg operations
with and without DIB.
In my particular case, images were 384x288x24bit (not too big, not too small
:-)) .
Sergei Soudakov
So Made your own jpg compressor as i did.
Its public and free pasjpeg.zip .
I remade this library for my own purpose (for best speed)..
I am putting just pointer to RGB image and reding stream output.
I am using it for my Videoserver which push MJPeg picturs to the browser.
I made Directx X filter in VC++6 which can be use with delphi
and speed is around 15/17 fps on P200. 384x288x24bit
Icq:5459514 for more info
Well I _thought_ that we got C source in the box. Maybe not,
I can't find it right now. (But I don't have the CD here. Surely
there's a directory somewhere on the D3 CD with the jpeg source?
I could swear there was.)
Hmm, have you got a copy of the D3 readme.txt? It says
"The Delphi CD ROM includes the following files and directories.
[...]
\INFO Contains subdirectories with information and
third-party demo products. The \INFO\EXTRAS
directory contains source code and other files
for JPEG and FIF graphics formats, and for
data-compression algorithms; for more information,
see INFO\EXTRAS\EXTRAS.TXT."
Worth a try...
Davie
Sergei Soudakov wrote:
> > Must be a way to simply copy the compressed luminosity data without
> >ever decompressing it(???), but possibly not with TJPEGImage(???).
> But how?? ... I could only dream about that. Do you (or anybody) know, is a
> source of TJpegImage available? I've heared some time ago, that it was in D2
> (old good days :-) ), but it is no more than a rumour...
>
Sergei Soudakov.
I found the beast in \INFO\EXTRAS on my D4 CD.
It seems I had wrong feeling that D4 installer put everything I need on HD.
So, once I upgraded my D3, put D4 CD on a shelf and never touched it againg.
Big mistake...
:-)
Sergei Soudakov.
Fabulous. If you figure out how to extract the luminosity
from a JPEG without doing any decompressing at all let us know.
> It seems I had wrong feeling that D4 installer put everything I need on HD.
> So, once I upgraded my D3, put D4 CD on a shelf and never touched it againg.
> Big mistake...
> :-)
>
> Sergei Soudakov.
--