Skip to content

Instantly share code, notes, and snippets.

@chaidhat
Last active June 6, 2024 22:54
Show Gist options
  • Save chaidhat/5006fc94c98d22cae598749c7de86717 to your computer and use it in GitHub Desktop.
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
/*
* 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
@chaidhat
Copy link
Author

chaidhat commented May 4, 2019

Screenshot 2019-05-04 at 6 02 05 pm

@chaidhat
Copy link
Author

chaidhat commented May 5, 2019

output_b9m2QA

@JinBridger
Copy link

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? :)

@chaidhat
Copy link
Author

chaidhat commented Jun 6, 2024

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