Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Bilinear filtering of images  (Read 1926 times)
0 Members and 1 Guest are viewing this topic.
Offline EgonOlsen
« Posted 2004-12-14 17:23:45 »

While playing around with Java's crappy image-stuff, i wrote a simple method to zoom (downscaling is possible, but doesn't make much sense using this algo) an image using a bilinear filter. It's halfway optimized (using fixedpoint) and maybe somebody finds it usefull. It doesn't really fit into anything else i'm doing, so i decided to release it here instead:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
import java.awt.*;
import java.awt.image.*;

public class ImageUpscale {

  public static Image upscale(Image img, int width, int height) throws Exception {

    final int ACC = 512;
    final int ACCHX;
    final int ACCHY;
    final int ACCS = 9;
    final int ACCSD = ACCS << 1;
    final int ACCMASK = ~511;

    int sWidth = img.getWidth(null);
    int sHeight = img.getHeight(null);
    int length = sWidth * sHeight;
    int[] pixels = new int[length];
    PixelGrabber pg = new PixelGrabber(img, 0, 0, sWidth, sHeight, pixels, 0, sWidth);
    pg.grabPixels();

    BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    DataBufferInt data = (DataBufferInt) (dest.getRaster().getDataBuffer());
    int[] dPixels = data.getData();

    double xf = (double) sWidth / (double) width;
    double yf = (double) sHeight / (double) height;

    if (xf == (int) xf) {
         ACCHX = ACC >> 1;
    }
    else {
         ACCHX = 0;
    }

    if (yf == (int) yf) {
         ACCHY = ACC >> 1;
    }
    else {
         ACCHY = 0;
    }

    int xfI = (int) (xf * ACC);
    int yfI = (int) (yf * ACC);

    int sWidthACC = sWidth << ACCS;
    int sHeightACC = sHeight << ACCS;
    int fsy = 0;
    for (int y = 0; y < height; y++) {

      int floorY = fsy & ACCMASK;
      int ceilY = floorY + ACC;
      if (ceilY >= sHeightACC) {
        ceilY = floorY;
      }
      int fracY = (fsy & ~ACCMASK) + ACCHY;
      int oppY = ACC - fracY;
      int yPos = y * width;
      int fyW = (floorY * sWidth) >> ACCS;
      int cyW = (ceilY * sWidth) >> ACCS;

      int fsx = 0;
      int end = width + yPos;

      for (int x = yPos; x < end; x++) {

        int floorX = fsx & ACCMASK;
        int fracX = (fsx & ~ACCMASK) + ACCHX;
        int oppX = ACC - fracX;
        int ceilX = floorX + ACC;
        if (ceilX >= sWidthACC) {
          ceilX = floorX;
        }

        int c1 = pixels[ (floorX >> ACCS) + fyW];
        int c2 = pixels[ (ceilX >> ACCS) + fyW];
        int c3 = pixels[ (floorX >> ACCS) + cyW];
        int c4 = pixels[ (ceilX >> ACCS) + cyW];

        int c1r = (c1 >> 16) & 255;
        int c1g = (c1 >> 8) & 255;
        int c1b = c1 & 255;

        int c2r = (c2 >> 16) & 255;
        int c2g = (c2 >> 8) & 255;
        int c2b = c2 & 255;

        int c3r = (c3 >> 16) & 255;
        int c3g = (c3 >> 8) & 255;
        int c3b = c3 & 255;

        int c4r = (c4 >> 16) & 255;
        int c4g = (c4 >> 8) & 255;
        int c4b = c4 & 255;

        int cc1 = oppX * c1r + fracX * c2r;
        int cc2 = oppX * c3r + fracX * c4r;
        int r = (oppY * cc1 + fracY * cc2) >> ACCSD;

        cc1 = oppX * c1g + fracX * c2g;
        cc2 = oppX * c3g + fracX * c4g;
        int g = (oppY * cc1 + fracY * cc2) >> ACCSD;

        cc1 = oppX * c1b + fracX * c2b;
        cc2 = oppX * c3b + fracX * c4b;
        int b = (oppY * cc1 + fracY * cc2) >> ACCSD;

        dPixels[x] = (r << 16) | (g << 8) | b;
        fsx += xfI;
      }
      fsy += yfI;
    }
    return dest;
  }
}

Offline Malohkan

Senior Duke




while (true) System.out.println("WOO!!!!");


« Reply #1 - Posted 2004-12-15 03:46:42 »

wow I just played with that and it works really well!  Very good job! Smiley

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline Herkules

Senior Duke




Friendly fire isn't friendly!


« Reply #2 - Posted 2004-12-15 05:55:15 »

Reminds me of some MMX code I once wrote.

<proud>
Did the filtering with nearly no overhead against a pure image copy by using memory wait times and such.
</proud>

It was used for displaying smoke/fire effects in a game, where a texture has to be scale-copied to the screen. With MMX, it has been filtered ... looked really nice!


HARDCODE    --     DRTS/FlyingGuns/JPilot/JXInput  --    skype me: joerg.plewe
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline role

Junior Duke




Java manmoth is coming!


« Reply #3 - Posted 2004-12-16 22:38:42 »

What's wrong with Java2D scaling?  Huh
Can't see much difference?
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
private static final GraphicsConfiguration gc =
   GraphicsEnvironment.getLocalGraphicsEnvironment().
      getDefaultScreenDevice().getDefaultConfiguration();

public static BufferedImage resize(BufferedImage src, int w, int h) {
   int transparency = src.getColorModel().getTransparency();
   BufferedImage image = gc.createCompatibleImage(w, h, transparency);

   Graphics2D g = image.createGraphics();
   g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
   g.drawImage(src,
               0, 0, w, h, // destination
               0, 0, src.getWidth(), src.getHeight(), // source
               null);
   g.dispose();

   return image;
}

Golden T Game Engine - Java2D/OpenGL Game Engine
Golden T Website | Golden T Forum
Offline EgonOlsen
« Reply #4 - Posted 2004-12-17 03:49:05 »

Quote
What's wrong with Java2D scaling?  Huh
Can't see much difference?
It's not a much of a visible difference, but i had the problem, that Java's stuff was crashing with out of memory in some cases, where mine will still work and my method is a little faster (but not that much...then again, it haven't spend much time optimizing it). In addition, i wanted something that will work on simple arrays (for resizing textures and the framebuffer in jPCT) apart from all the Image-stuff.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (45 views)
2014-10-17 03:59:02

Norakomi (36 views)
2014-10-16 15:22:06

Norakomi (27 views)
2014-10-16 15:20:20

lcass (31 views)
2014-10-15 16:18:58

TehJavaDev (61 views)
2014-10-14 00:39:48

TehJavaDev (61 views)
2014-10-14 00:35:47

TehJavaDev (51 views)
2014-10-14 00:32:37

BurntPizza (67 views)
2014-10-11 23:24:42

BurntPizza (39 views)
2014-10-11 23:10:45

BurntPizza (81 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!