| /******************************************************************************* |
| * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| <<<<<<< HEAD |
| * Pierre Allard - initial API and implementation |
| * |
| ======= |
| * Pierre Allard - initial API and implementation |
| * |
| >>>>>>> refs/heads/eclipse_pa |
| * SPDX-License-Identifier: EPL-1.0 |
| *******************************************************************************/ |
| package org.eclipse.apogy.core.environment.earth.surface.ui.jme3.internal; |
| |
| import java.awt.Color; |
| import java.awt.Graphics; |
| import java.awt.image.BufferedImage; |
| import java.io.File; |
| import java.io.IOException; |
| |
| public class SunGlowImageGenerator { |
| public static final int TRANSPARENT_COLOR = -1; |
| |
| public static int getColor(double value) { |
| if (value >= 0) { |
| float factor = (float) (1.0 - value); |
| |
| if (factor < 0) |
| factor = 0; |
| if (factor > 1) |
| factor = 1; |
| |
| float hue = 0.0f; |
| |
| if (factor < 0.5f) { |
| hue = ((0.5f - factor) / 0.5f) * 0.1f; |
| } else { |
| hue = 1.0f - (((factor - 0.5f) / 0.5f) * 0.1f); |
| } |
| |
| Color color = Color.getHSBColor(hue, 0.9f, 0.9f); |
| return color.getRGB(); |
| } else { |
| return TRANSPARENT_COLOR; |
| } |
| } |
| |
| public static double f(double x) { |
| double a5 = -0.0000000000507451403; |
| double a4 = 0.00000008635031873; |
| double a3 = -0.00005722601654; |
| double a2 = 0.01861529584; |
| double a1 = -3.114455857; |
| double a0 = 255.7552448; |
| |
| // return (50 * (1.0 /(0.02 * (x - 10)))) + 3; |
| // return (1 * (1.0 /(0.02 * (x - 10)))) + 3; |
| |
| return a5 * Math.pow(x, 5) + a4 * Math.pow(x, 4) + a3 * Math.pow(x, 3) + a2 * Math.pow(x, 2) |
| + a1 * Math.pow(x, 1) + a0; |
| } |
| |
| public static double getDistanceOLD(double x, double y, int width) { |
| double curveValue = f(x); |
| if (y > curveValue) { |
| return -1; |
| } else { |
| double xp = 0; |
| double yp = 0; |
| double distance = Double.POSITIVE_INFINITY; |
| for (int i = 0; i < width; i++) { |
| yp = f(i); |
| double d = Math.sqrt((x - i) * (x - i) + (y - yp) * (y - yp)); |
| if (d < distance) { |
| xp = i; |
| distance = d; |
| } |
| } |
| |
| yp = f(xp); |
| |
| /* |
| * double m = (yp-y) / (xp -x); double b = yp - (m*xp); double y0 = b; double x0 |
| * = -b/m; |
| * |
| * double xyDistance = 0; if(y0 >= 0) { xyDistance = Math.sqrt((x*x) + (y - y0) |
| * *(y-y0)); } else { xyDistance = Math.sqrt((x-x0) * (x-x0) + (y*y)); } |
| * |
| * double value = distance / (xyDistance + distance); if(value > 1) value = 1; |
| * return value; |
| */ |
| |
| return 1.0 - (xp / width); |
| } |
| } |
| |
| public static BufferedImage generateImageOLD(int width, int height) { |
| double[][] distances = new double[width][height]; |
| for (int x = 0; x < width; x++) { |
| for (int y = 0; y < height; y++) { |
| double distance = SunGlowImageGenerator.getDistanceOLD(x, y, width); |
| // double distance = (1.0 * x) / width; |
| |
| distances[x][y] = distance; |
| } |
| } |
| |
| /* |
| * // Find min max distances. double min = Double.POSITIVE_INFINITY; double max |
| * = Double.NEGATIVE_INFINITY; for(int x=0; x< width; x++) { for(int y=0; y< |
| * height; y++) { double distance = distances[x][y]; if(distance < min) { min = |
| * distance; } |
| * |
| * if(distance > max) { max = distance; } } } |
| * |
| * // Normalize. for(int x=0; x< width; x++) { for(int y=0; y< height; y++) { |
| * double distance = distances[x][y]; double n = (distance - min)/(max-min); |
| * distances[x][y] = n; } } |
| */ |
| |
| int[][] pixelColors = new int[width][height]; |
| for (int x = 0; x < width; x++) { |
| for (int y = 0; y < height; y++) { |
| int color = getColor(distances[x][y]); |
| pixelColors[x][y] = color; |
| } |
| } |
| |
| BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
| Graphics g = bufferedImage.createGraphics(); |
| g.setColor(new Color(0, 0, 0, 0)); |
| g.fillRect(0, 0, width, height); |
| |
| for (int x = 0; x < width; x++) { |
| for (int y = 0; y < height; y++) { |
| int rgb = pixelColors[x][y]; |
| |
| if (rgb != TRANSPARENT_COLOR) { |
| bufferedImage.setRGB(x, height - 1 - y, rgb); |
| } |
| } |
| } |
| |
| return bufferedImage; |
| } |
| |
| public static void applyGrayscaleMaskToAlpha(BufferedImage image) { |
| final int width = image.getWidth(); |
| int[] imgData = new int[width]; |
| |
| for (int y = 0; y < image.getHeight(); y++) { |
| // fetch a line of data from each image |
| image.getRGB(0, y, width, 1, imgData, 0, 1); |
| |
| // int[][] filter = new int[3][3]; |
| // int i = 0; |
| for (int x = 0; x < width; x++) { |
| int color = imgData[x] & 0x00FFFFFF; // mask away any alpha present |
| |
| /* |
| * int r = (color & 0x00FF0000) >> 16; int g = (color & 0x0000FF00) >> 8; int b |
| * = (color & 0x000000FF) >> 0; |
| * |
| * // System.out.println(r + ", " + g + "," + b); |
| * |
| * filter[i][0] = r; filter[i][1] = g; filter[i][2] = b; |
| * |
| * i++; if(i >= filter.length) i = 0; |
| * |
| * int tempR = 0; int tempG = 0; int tempB = 0; for(int j = 0; j < |
| * filter.length; j++) { tempR += filter[j][0]; tempG += filter[j][1]; tempB += |
| * filter[j][2]; } |
| * |
| * tempR = (int) (1.0 * tempR / (1.0 * filter.length)); tempG = (int) (1.0 * |
| * tempG / (1.0 * filter.length)); tempB = (int) (1.0 * tempB / (1.0 * |
| * filter.length)); |
| * |
| * // System.out.println(tempR + ", " + tempG + "," + tempB); |
| * |
| * |
| * color = 0xFF000000 | (tempR << 16) | (tempG << 8) | (tempB << 0); |
| */ |
| /// int maskColor = (maskData[x] & 0x00FF0000); // shift red into alpha bits |
| |
| if (color != 0) { |
| float intensity = (1.0f - (1.0f * x / width)) * 200; |
| |
| if (x == 0) |
| intensity = 255f; |
| |
| System.out.println(intensity); |
| |
| int maskColor = (int) Math.floor(intensity); |
| maskColor = maskColor << 24; |
| color |= maskColor; |
| imgData[x] = color; |
| } else { |
| |
| } |
| } |
| // replace the data |
| image.setRGB(0, y, width, 1, imgData, 0, 1); |
| } |
| } |
| |
| /* |
| * public static void applyGrayscaleMaskToAlpha(BufferedImage image, |
| * BufferedImage mask) { int width = image.getWidth(); int height = |
| * image.getHeight(); |
| * |
| * int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width); int[] |
| * maskPixels = mask.getRGB(0, 0, width, height, null, 0, width); |
| * |
| * for (int i = 0; i < imagePixels.length; i++) { int color = imagePixels[i] & |
| * 0x00ffffff; // Mask preexisting alpha int alpha = maskPixels[i] << 24; // |
| * Shift blue to alpha imagePixels[i] = color | alpha; } |
| * |
| * image.setRGB(0, 0, width, height, imagePixels, 0, width); } |
| */ |
| |
| public static double getClosestX(int y, int width) { |
| double xp = 0; |
| double yp = 0; |
| double distance = Double.POSITIVE_INFINITY; |
| for (int x = 0; x < width; x++) { |
| yp = f(x); |
| |
| // System.out.println("f(" + x + ") = " + yp); |
| |
| double d = Math.sqrt((y - yp) * (y - yp)); |
| if (d < distance) { |
| xp = x; |
| distance = d; |
| } |
| } |
| |
| return xp; |
| } |
| |
| public static BufferedImage generateImage(int width, int height) { |
| float[] distances = new float[height]; |
| |
| for (int x = 0; x < height; x++) { |
| double xp = getClosestX(x, width); |
| distances[x] = (float) xp; |
| } |
| |
| int[][] pixelColors = new int[width][height]; |
| for (int x = 0; x < width; x++) { |
| for (int y = 0; y < height; y++) { |
| double factor = 0; |
| |
| if (x < distances[y]) { |
| factor = 1.0 - (1.0 * x / width); |
| } else { |
| factor = -1; |
| } |
| |
| if (factor != -1) { |
| /// int color = getColor(factor); |
| int color = getColor(factor) & 0x00FFFFFF; |
| float distance = distances[y]; |
| if (y < 10) { |
| float intensity = 255; |
| if (x >= 256) { |
| intensity = (1.0f - ((x - 256) / (width - 256))) * 255; |
| } |
| |
| int maskColor = (int) Math.floor(intensity); |
| maskColor = maskColor << 24; |
| color |= maskColor; |
| } else { |
| float intensity = (1.0f - (1.0f * x / distance)) * 255; |
| int maskColor = (int) Math.floor(intensity); |
| maskColor = maskColor << 24; |
| color |= maskColor; |
| } |
| pixelColors[x][y] = color; |
| } |
| } |
| } |
| |
| BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
| Graphics g = bufferedImage.createGraphics(); |
| g.setColor(new Color(0, 0, 0, 0)); |
| g.fillRect(0, 0, width, height); |
| |
| for (int x = 0; x < width; x++) { |
| for (int y = 0; y < height; y++) { |
| int rgb = pixelColors[x][y]; |
| |
| if (rgb != TRANSPARENT_COLOR) { |
| bufferedImage.setRGB(x, height - 1 - y, rgb); |
| } |
| } |
| } |
| |
| // Sets first column to white. |
| Color color = new Color(255, 255, 234); |
| int rgb = color.getRGB(); |
| |
| for (int y = 0; y < height; y++) { |
| bufferedImage.setRGB(0, y, rgb); |
| } |
| |
| return bufferedImage; |
| } |
| |
| public static void main(String[] args) { |
| int width = 512; |
| int height = 256; |
| |
| BufferedImage image = SunGlowImageGenerator.generateImage(width, height); |
| |
| // BufferedImage mask = null; |
| |
| /* |
| * try { image = javax.imageio.ImageIO.read(new |
| * File("/home/pallard/Pictures/testglow.png")); } catch (IOException e1) { |
| * e1.printStackTrace(); } |
| * |
| * try { mask = javax.imageio.ImageIO.read(new |
| * File("/home/pallard/Pictures/mask.png")); } catch (IOException e1) { |
| * e1.printStackTrace(); } |
| * |
| */ |
| |
| File file = new File("/home/pallard/Pictures/test.png"); |
| try { |
| javax.imageio.ImageIO.write(image, "png", file); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| |
| // for(int x = 0; x < 512; x++) |
| // { |
| // System.out.println("f(" + x + ") = " + f(x) ); |
| // } |
| } |
| |
| } |