Last active
June 6, 2024 22:54
-
-
Save chaidhat/5006fc94c98d22cae598749c7de86717 to your computer and use it in GitHub Desktop.
Downloads Meterological Images (visible band) from Himawari 8 Geo-stationary Satellite, colour corrects it and sets desktop with realtime images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Himawari 8 Satellite | |
* Chaidhat Chaimongkol 2 May 2019 | |
* Downloads Meterological Images (visible band) from http://www.jma.go.jp/jma/en/menu.html and sets desktop with realtime, colour corrected, geo-stationary images | |
* The Japan Meterological Agency's Himawari Geostationary Satellite | |
* | |
* Sets desktop wallpaper to realtime image of Himawari every 10 minutes, which are recent from 5-15 minutes | |
* For ONLY Mac Mojave ++, uses Java and Applescript and exported as .jar file. | |
* Created for no reason at all, all code is Chai's | |
* | |
* IMPORTANT: FOR MAC MOJAVE AND ALSO ADD A FOLDER ON DESKTOP CALLED 'image'!!! | |
* Color correction reference to: https://loneskyimages.blogspot.com/2017/05/himawari-8-color-correction.html | |
* GIMP color correction: https://docs.gimp.org/2.6/en/plug-in-colors-channel-mixer.html | |
* AP and Java Integration: https://alvinalexander.com/blog/post/java/how-run-multi-multiple-line-applescript-java-program | |
* Other than that, documentation were used for Applescript and Java. | |
* | |
* ![Screenshot 2019-05-04 at 6 02 05 pm](https://user-images.githubusercontent.com/41228307/57180814-f4e21200-6e7b-11e9-9f9c-f3b15c58158a.png) | |
* Compile it to jar file and run. It assumes your in 7+UTC | |
*/ | |
package NonAcademic; | |
import java.util.Scanner; | |
import javax.imageio.ImageIO; | |
import org.omg.CORBA.portable.InputStream; | |
import java.awt.Color; | |
import java.awt.image.BufferedImage; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.net.URL; | |
import java.util.Date; | |
import java.util.TimeZone; | |
import java.util.concurrent.TimeUnit; | |
import java.text.SimpleDateFormat; | |
public class Himawari8SatDesktop | |
{ | |
public static String yr, d, m, hr, min = "00"; | |
static float rt = 0, gt = 0, bt = 0, rot = 0, got = 0, bot = 0, r, g, b, rc, gc, bc, ro, go, bo, h = 0, s = 0, l = 0, max, minn, t1, t2; | |
public static void main(String[] args) throws IOException, InterruptedException | |
{ | |
while (true) | |
{ | |
// get the date and time UTC | |
Date date = new Date(); | |
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); | |
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); | |
yr = dateFormat.format(date).substring(6, 10); | |
d = buffer(Integer.parseInt(dateFormat.format(date).substring(0, 2))); | |
m = buffer(Integer.parseInt(dateFormat.format(date).substring(3, 5))); | |
// get 5 minutes ago because JMA upload it 5 minutes after the picture was taken. | |
// round it to ten minutes | |
int hoffset = 0; | |
System.out.println(Math.floor((((float)(Integer.parseInt("55"))) - 5) / 10) * 10); | |
if (Math.floor(((float)(Integer.parseInt(dateFormat.format(date).substring(14, 16))) - 5) / 10) * 10 < 0) | |
{ | |
hoffset = 1; | |
min = "50"; | |
} | |
else | |
{ | |
min = buffer((int)Math.floor(((float)(Integer.parseInt(dateFormat.format(date).substring(14, 16))) - 5) / 10) * 10); | |
} | |
hr = buffer(Integer.parseInt(dateFormat.format(date).substring(11, 13)) - hoffset % 24); | |
System.out.println(dateFormat.format(date)); | |
System.out.println(yr + m + d + hr + min); | |
// new image | |
BufferedImage inImage = null; | |
try{ | |
// jma uses format yr m d hr min -00 so like 201905040110-00 | |
URL url =new URL("http://www.jma.go.jp/en/gms/imgs_c/6/visible/1/" + yr + m + d + hr + min + "-00.png"); | |
// read the url | |
inImage = ImageIO.read(url); | |
// image colour correction | |
// Image dimensions | |
int imageWidth = inImage.getWidth(); | |
int imageHeight = inImage.getHeight(); | |
BufferedImage outImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_ARGB); | |
// determine luminosity (add all RGB and color corrected RGB) to preform Color Channel mixing with preserved luminosity | |
System.out.println("download complete, colour correction"); | |
for (int x = 0; x < outImage.getWidth(); x++) { | |
for (int y = 0; y < outImage.getHeight(); y++) { | |
// get RGB of pixel xy | |
r = new Color(inImage.getRGB(x,y)).getRed(); | |
g = new Color(inImage.getRGB(x,y)).getGreen(); | |
b = new Color(inImage.getRGB(x,y)).getBlue(); | |
// colour corrected | |
rot += (r + (g * 0.125)) / 255; | |
got += ((r * 0.25) + g) / 255; | |
bot += ((r * 0.125) + b) / 255; | |
// raw colour | |
rt += r / 255; | |
gt += g / 255; | |
bt += b / 255; | |
} | |
} | |
// luminosity multiplier to preserve luminosity | |
rc = rt / rot; | |
gc = gt / got; | |
bc = bt / bot; | |
for (int x = 0; x < outImage.getWidth(); x++) { | |
for (int y = 0; y < outImage.getHeight(); y++) { | |
r = new Color(inImage.getRGB(x,y)).getRed(); | |
g = new Color(inImage.getRGB(x,y)).getGreen(); | |
b = new Color(inImage.getRGB(x,y)).getBlue(); | |
int pixelColorInt; | |
// that blue band at the bottom is removed | |
if (r == 0 && g == 0 && b == 128) | |
{ | |
pixelColorInt = new Color(0, 0, 0, 255).getRGB(); | |
} | |
else | |
{ | |
// colour channel change | |
// red = 25% green | |
// green = 50% red | |
// blue = 25% red | |
ro = Math.min((float) (r + (g * 0.125)) * rc,254) / 255; | |
go = Math.min((float) ((r * 0.25) + g) * gc,254) / 255; | |
bo = Math.min((float) ((r * 0.125) + b) * bc,254) / 255; | |
// convert RGB to HSV | |
float[] hsv = new float[3]; | |
Color.RGBtoHSB((int) (ro * 255), (int) (go * 255),(int) (bo * 255),hsv); | |
// Hue change by 0.139 deg | |
// Sat change by 200 | |
hsv[0] *= 1.05; | |
//hsv[1] -= 0.5f; | |
hsv[1] *= 2f; | |
//hsv[1] += 0.5f; | |
hsv[1] = Math.min(Math.max(hsv[1], 0), 1); | |
ro = (float)new Color(Color.HSBtoRGB(hsv[0], hsv[1], hsv[2])).getRed() / 255; | |
go = (float)new Color(Color.HSBtoRGB(hsv[0], hsv[1], hsv[2])).getGreen() / 255; | |
bo = (float)new Color(Color.HSBtoRGB(hsv[0], hsv[1], hsv[2])).getBlue() / 255; | |
// Constrast filter, applied in RGB because I have no idea how HSB works. | |
ro = Math.min((((ro * 255) - 0.7f) * 1.1f) + 0.7f * 2f, 254) / 255; | |
go = Math.min((((go * 255) - 0.7f) * 1.1f) + 0.7f * 2f, 254) / 255; | |
bo = Math.min((((bo * 255) - 0.7f) * 1.1f) + 0.7f * 2f, 254) / 255; | |
// 0.0-1.0 color, not 0-255 | |
// now set color to the RGB. | |
pixelColorInt = new Color(ro, go, bo, 1).getRGB(); | |
} | |
outImage.setRGB(x, y, pixelColorInt); | |
} | |
} | |
System.out.println("writing file"); | |
// for png | |
ImageIO.write(outImage, "png",new File("/Users/chaidhatchaimongkol/Desktop/image/image" + yr + m + d + hr + min + ".png")); | |
System.out.println("done! Setting background..."); | |
}catch(IOException e){ | |
// write applescript and execute | |
e.printStackTrace(); | |
} | |
new Himawari8Sat(); | |
System.out.println("end. " + hr + min); | |
TimeUnit.MINUTES.sleep(1); | |
} | |
} | |
//} | |
public Himawari8Sat() | |
{ | |
// https://alvinalexander.com/blog/post/java/how-run-multi-multiple-line-applescript-java-program | |
Runtime runtime = Runtime.getRuntime(); | |
// an applescript command that is multiple lines long. | |
// just create a java string, and remember the newline characters. | |
String applescriptCommand = | |
"tell application \"Finder\" to set a to (desktop picture) as string\n" + | |
"tell application \"Image Events\"\n" + | |
"launch\n" + | |
"set Wallpaper to open \"~/Desktop/image/image" + yr + m + d + hr + min + ".png\"\n" + | |
"pad Wallpaper to dimensions {2000, 1800} with pad color {0, 0, 0}\n" + | |
"save Wallpaper\n" + | |
"close Wallpaper\n" + | |
"end tell\n" + | |
"if (a contains \"Macintosh HD:Users:chaidhatchaimongkol:Desktop:image\" or a is \"Macintosh HD:Users:chaidhatchaimongkol:Desktop:image1.png\") then\n" + | |
"tell application \"System Events\"\n" + | |
"tell current desktop\n" + | |
"set picture to \"~/Desktop/image/image" + yr + m + d + hr + min + ".png\"\n" + | |
"end tell\n" + | |
"end tell\n" + | |
"end if"; | |
String[] args = { "osascript", "-e", applescriptCommand }; | |
try | |
{ | |
Process process = runtime.exec(args); | |
} | |
catch (IOException e) | |
{ | |
e.printStackTrace(); | |
} | |
} | |
public static String buffer (int y) | |
{ | |
String x = Integer.toString(y); | |
if (x.length() == 1) | |
return "0" + x; | |
if (x.length() == 2) | |
return x; | |
return ""; | |
} | |
} //Himawari8Sat |
Author
chaidhat
commented
May 4, 2019
hi @chaidhat! Thanks for your excellent work. But it seems not working now (e.g. the website has changed). Could you please kindly take a look and make some necessary updates? :)
Hi @JinBridger thanks for expressing interest in this! Unfortunately, I don't have enough time to work on it atm -- please feel free to modify/redistribute it though, it's licensed under MIT! :)
If you have any qs please email me at chaimongkol at ucla dot edu since I don't check Github that often!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment