|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Tue Apr 28, 2009 1:09 pm Post subject: Scaling JPEG images |
|
|
When I create an offscreen grapics region, import a JPEG image and then transfer it to the screen, I have the following problems:
1. Scaling the size down wrecks the image quality. I am trying to create thumbnails. Increasing the scale is OK.
2. The graphics window handle, which I believe is "User supplied", changes to zero during the existence of the window, and back to its original value when the window is destroyed. This means that routines which reference the window handle do not work and a separate handle is required.
3. The original image downloads from the camera fails to be accepted. It is necessary to open the image in another program and re-save it. I used "Irfanview" which is great for batch processing purposes. Camera was KonicaMinolta Z5.
The link below gives the source, compilation listing, project and JPEGs.
Regards
Ian
http://norsoftdev.com/silverfrost/offshorephotos.zip |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Apr 28, 2009 3:10 pm Post subject: |
|
|
I don't have time to look at your code right now but I jsut want to check if you know about the routine set_jpeg_quality@. Having said this, it probably is not relevant to your needs. |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Tue Apr 28, 2009 6:19 pm Post subject: |
|
|
Paul,
I have used set_jpeg_quality@ in the past, but the documentation suggests it is for exporting images to a file. My program imports an image from a file and displays it. It is OK for a scale of 1:1 and above, but not scaling down.
Regards
Ian |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Tue Jun 02, 2009 12:23 pm Post subject: |
|
|
Paul,
Just wondering if you could look at this one sometime.
Regards
ian |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Jun 03, 2009 2:04 pm Post subject: |
|
|
Ian
I doubt that item 1 can be resolved in a reasonable amount of time.
I was responsible for importing all of the JPEG stuff into ClearWin+ and the algorithms are very complex.
Given the current pressures on my time, I may only be able to investigate items 2 and 3 on a consultancy basis. If you are interested in this then please contact Silverfrost in the first instance.
Regards
Paul |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Wed Jun 03, 2009 4:08 pm Post subject: |
|
|
Paul,
Thanks for your response, my comments on the items are:
1. The scaling is carried out using COPY_GRAPHICS_REGION@. Is this just a link to a Microsoft API? If so, it may be that at fault and it may not be able to shrink the image in the same way that it can stretch an image. There may be another way to process the jpeg to shrink it which I would be pleased if you could point me to. Such as GET_DIB_BLOCK@ and DISPLAY_DIB_BLOCK@ and to manually select/average the pixels from the imported array to reduce the size as necessary and create a new array, even though this could be process intensive. Or are you aware of another API function?
2. I think that this is a bug in either the software or requires a comment in the help. The handle acts differently depending on whether it is a screen or printer/offscreen area.
3. KonicaMinolta no longer make cameras and it would be much cheaper for me to buy a new camera or to keep using Irfanview. The latter option being the most likely.
Items 2& 3 were informative.
Regards
Ian |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Mon Jun 08, 2009 10:34 pm Post subject: |
|
|
Ian,
I remember playing wih some forum-user's code that resized a graphic - I'm sure it was a JPEG - but although I just went through the forum looking for the thread I couldn't find it. He was getting corruption, and it was solved by modifying the algorithm for computing new pixel colours.
I wonder if you have tried this with, say, a BMP file. If it works, then there is something in the handling of JPEGs, if it doesn't, then it is in COPY_GRAPHICS_REGION@. In any case, if you do repeated JPEG compression/decompression on an image the colours rapidly go haywire.
The handle issue is answered by Paul in his reply to my thread entitled "When is a handle not a handle?" - and I found several other threads on the same theme in my hunt for that elusive code.
Buying a new camera isn't much of an answer - they all do JPEGs. I also have a Minolta. It will do quite low pixel-count images if you set it right. My newer cameras don't - they won't do a 640x480 (VGA) image for instance. A 640x480 image can be quite detailed.
Eddie |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Mon Jun 08, 2009 11:29 pm Post subject: |
|
|
Eddie,
I have just tried .BMPs instead - same result I'm afraid.
Thanks for that info about handles and hopefully the help will catch up eventually.
I'll have to think about another way of scaling down.
Regards
Ian |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Jun 09, 2009 1:08 pm Post subject: |
|
|
Hi Ian,
Scaling down a coloured image is a matter of transforming from an array mx*nx of cells a*b in size with RGB colour values for each cell to a smaller array nx*ny of cells c*d in size with RGB colour values related in some way to the original grid. If the aspect ratio remains the same, especially if a=b and c=d (so that the cells are square), the problem is simplified. In any case, it is simply a matter of filling nx*ny with appropriate colour values.
The simplest way of doing this is to operate on the centres of the cells. The new cell colour is the colour of the old cell whose centre is closest to the centre of the new cell. There are then 3 cases: simplest is where there is only one choice. That guarantees no colour change in the image, because only old colours are used. However, you may have 2 or 4 old cell centroids equidistant. Again, if you opt for one of the 2 or 4, there can be no colour shift. Alternatively, you can take an average. In that case, you must decompose the RGB values into R, G & B, and average each before reassembling them, taking care that each final component is a number between 0 and 255 inclusive.
If you want to be more sophisticated, you can average the R, G & B values of all old cells overlapped by a new cell, perhaps on the basis of area appearing in the new cell. The new cell RGB colours are then unavoidably different to the old image. You might minimise this shift by weighting large areas more than small ones.
If you have a background in finite element theory (an informed guess on my part), you might consider using shape function interpolation, treating the old grid as nodes defining square elements, and each new grid node as a point within a particular element. However, individual colour components need to be interpolated separately and recombined afterwards. Lagrangian interpolation is a more sophisticated alternative that would take into account more than the four nearest old cell centroids. If you haven't worked with finite elements, then ignore this paragraph!
Regards
Eddie |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Tue Jun 09, 2009 1:28 pm Post subject: |
|
|
Eddie,
Thanks very much, that is a great idea using the FEA mapping function. I will have a think about it. I think that c & d would always be 1 in my case, and a & b would be equal. I am only interested in a rough but colour-realistic thumbnail so it might be quite simple. As scaling up seems to work, I could pre-process the input picture to a standard size, maintaining aspect ratio and then pass the result through a standard reduction algorithm so that the thumbnails are always the same final size.
I'll let you know when I summon up the energy to have a go.
Regards
Ian |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Jun 09, 2009 1:46 pm Post subject: |
|
|
Ian,
I knew you were happy with FEA! Use 4-noded serendipity elements. The xi and eta coords come from the shift between the old grid and the new. You don't need to worry about coordinate transformation and Jacobian determinants etc. because the old grid is rectangular ...
Eddie
Last edited by LitusSaxonicum on Wed Jun 10, 2009 9:02 am; edited 1 time in total |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Jun 10, 2009 3:37 am Post subject: |
|
|
Ian,
I tried the example photo you supplied in your download and saw the problem when reducing the size. It is not very good.
I'd be surprised if this problem is as difficult as requiring Lagrangian interpolation when scaleing down. I use a palette of 120 graded colours for my shadeing of stress fields from Lagrangian elements and that looks more than adequate (to me).
I think a test using your own colour interpolation with a weighted average of red, green and blue seperately, with the weighting based on the area proportion would work well. The eye makes colour rendering fairly forgiving.
As for when expanding, I'm sure the interpolation being used is not that complex either.
I'd be interested in hearing what you find.
John |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Jun 10, 2009 9:01 am Post subject: |
|
|
John,
I wouldn't use higher-order Lagrangian interpolation in the first instance either ... the linear serendipity element shape function IS the same as a first order Lagrangian one.
Since learning about shape functions in c. 1971 I have used them for all sorts of interpolation.
My first shot was "use the colour of the (spatially) nearest old pixel" which is even simpler.
Eddie |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Wed Jun 10, 2009 9:30 pm Post subject: |
|
|
Eddie and John,
I was thinking that interpolation is perhaps more appropriate to increasing the density of an image. As I want to reduce it, an averaging technique may be more appropriate. I could of course be talking rubbish, a hobby of mine.
I'm still thinking about it.
Ian |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Wed Jun 10, 2009 10:10 pm Post subject: |
|
|
Hi chaps,
I've just had a go and simply picked the centre pixel from a rectangular area of the original image. If the thumbnail size is say 60 wide, then just step through the original image in 60 steps. Similarly in the vertical, create a new array with the reduced set and display it.
No interpolation and no averaging. It just seems to work.
Thanks for the hints and here is the code.
Ian
PS If the image is a line drawing, it is easy to miss narrow vertical and horizontal lines by this method, and perhaps the averaging method should be applied.
Code: |
WINAPP
INCLUDE <windows.ins>
CHARACTER*256 file
integer*1, allocatable a(:,:,:)
integer*1, allocatable b(:,:,:)
INTEGER hres,vres,nb_colours,ier,i,k,control,hres_new,vres_new
!c--- Note - you may need to alter this path
file='PICT2115.bmp'
CALL get_dib_size@(file,hres,vres,nb_colours,ier)
print *,hres,vres,ier,nb_colours
allocate (a(3,hres,vres))
CALL get_dib_block@(file,a,hres,hres,0,0,hres,vres,0,0,ier)
IF(ier.NE.0) STOP 'TROUBLE'
!allocate the thumbnail with the same aspect ratio as the original and the biggest size
! as 256 bits wide
imax_thumb_size = 60
if(hres .gt. vres)then
hres_new = imax_thumb_size
vres_new = vres*imax_thumb_size/hres
else
vres_new = imax_thumb_size
hres_new = hres*imax_thumb_size/vres
endif
print *,hres_new,vres_new
allocate (b(3,0:hres_new-1,0:vres_new-1))
ixratio = float(hres)/hres_new
iyratio = float(vres)/vres_new
ipickx_offset = ixratio/2
ipicky_offset = iyratio/2
print *,ixratio,iyratio,ipickx_offset,ipicky_offset
do ix = 0,hres_new-1
ix_orig = ipickx_offset + ix*ixratio
do iy = 0,vres_new-1
iy_orig = ipicky_offset + iy*iyratio
b(1:3,ix,iy) = a(1:3,ix_orig,iy_orig)
enddo
enddo
!c--- Display the image
i=winio@('%gr%lw',800,800,control)
CALL display_dib_block@(0,0,b,hres_new,vres_new,0,0,hres_new,vres_new,0,0,ier)
deallocate (a,b)
END
|
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|