画像圧縮ソフト改良版 Improved image compression software
画像の圧縮度合いを選べるようになりました!
Now you can choose the compression degree of the image !
In the middle, the original image,
v1 is an image with 256 colors,
v2 is an image with 65,500 colors.
真ん中が、元々の画像、
v1が色数256色の画像、
v2が色数65500色の画像です。
⇦ V 1 is 256 colors
I express pictures of dogs by just this color .
⇦V1は、256色
この色だけで、犬の写真を表現しています。
How to operate …
Start Processing and run it.
Drag and drop your favorite image onto the screen that came out.
Then, select the compression degree button, click it, and click Execute.
If you drag and drop the created file again, the compressed image will be displayed.
Click the Save button to complete the compressed image.
(The video is pasted at the end of this page.)
操作方法は、、、
Processingを起動し、実行。
出てきた画面に好きな画像をドラッグ&ドロップします。
そして、圧縮度合いのボタンを選んでクリックし、実行をクリック。
作られたファイルを再度ドラッグ&ドロップすると、圧縮後の画像が表示されます。
保存ボタンをクリックすれば、圧縮画像の完成です。
(このページの最後に動画が貼ってあります。)
ソースコードは、こちら↓ Source code is here
ASYUKU
PFont font; int mode = 0; PImage ins; int v; int d = 2; boolean x2; PImage bg; PImage bgh; PImage hed; boolean l = false; void Text(String t, float x, float y) { fill(0, 3); for (float i = -4; i < 5; i += 1) { for (float f = -4; f < 5; f += 1) { text(t, x+i, y+f); } } fill(255); text(t, x, y); } String passa; boolean one; void setup() { noStroke(); ins = loadImage("data/ins.png"); bg = loadImage("data/bg.png"); bgh = loadImage("data/bgh.png"); hed = loadImage("data/hed.png"); size(800, 480); dragDropFile(); surface.setTitle("圧縮"); } int en = 0; boolean cc; PImage img; void draw() { if (mode == 1) { background(100); if (bg != null)image(bg, 0, 0); font = createFont("MS PGothic", 32); if (font == null) { font = createFont("Osaka", 32); println("Osaka"); } if (font != null) { textFont (font); textSize(32); println("フォントロード成功"); String noload = "画像がまだロードされていません"; String noload2 = "このウィンドウにドラック&ドロップしてください。"; Text(noload, 400-(textWidth(noload)/2), 230); Text(noload2, 400-(textWidth(noload2)/2), 270); } mode = 2; } if (mode == 0) { if (ins != null)image(ins, 0, 0); mode = 1; } ; ; if (pass != null) { background(100); if (bg != null)image(bgh, 0, 0); println("ドロップされました "+pass); en = 0; println(); if (pass.substring(pass.length()-3, pass.length()).equals("kig")) { println("自作のやつです"); en = 1; } if (pass.substring(pass.length()-4, pass.length()).equals("kig2")) { println("v2の自作のやつです"); en = 2; } if (en == 0) { img = loadImage(pass); } if (en == 1) { img = ucon(loadBytes(pass)); } if (en == 2) { img = ucon2(loadBytes(pass)); } if (img != null) { float xs = img.width; float ys = img.height; int xss = int(xs); int yss = int(ys); float w = 1; if (xs > ys) { w = 640/xs; } else { w = 480/ys; } xs *= w; ys *= w; String str = xss+"x"+yss; textSize(24); Text(str, (640+80)-(textWidth(str)/2), 30); textSize(12); int fs = 0; if(v == 0)fs = filesize(img); if(v == 1)fs = filesize2(img); str = "予測サイズ"+nf(((float)fs/1024), 0, 2)+"KB "; if (en == 0)Text(str, (640+80)-(textWidth(str)/2), 50); println("ロードできました!"); println("拡大率は"+nf(w, 2, 2)+"%でした"); image(img, 320-(xs/2), 240-(ys/2), xs, ys); textSize(64); str = "実行"; if (en >= 1)str = "保存"; Text(str, (640+80)-(textWidth(str)/2), 460); l = true; } else { println("このファイルは壊れています"); } passa = pass; pass = null; } if (mouseX >= 640) { if (mouseY >= 480-90) { if (mousePressed && !cc) { one = true; cc = true; } else { cc = false; } } } if (one) { textSize(24); String str = "OK"; Text(str, (640+80)-(textWidth(str)/2), 460-64); if (en == 0) { if(x2)img = _2x(img); byte[] out = con(img); if(v == 1)out = con2(img); String a = ".kig"; //if(v == 1)a = ".kig2"; saveBytes(passa+a, out); println(passa+a+" に保存されました"); if(x2)img = _n2x(img); } if (en >= 1) { img.save(passa+".png"); println(passa+".png"+" に保存されました"); } one = false; } if(l){ image(hed,640,0); textSize(13); Text("バージョン(ベータ)",648,125); textSize(14); boolean p = false; if(bot("V1",644,130,v == 0)){ v = 0; p = true; } if(bot("V2",644+50,130,v == 1)){ v = 1; p = true; } Text("ディザリング レベル",648,125+60); if(bot(" 無し",644,130+60,d == 0)){ d = 0; p = true; } if(bot("控えめ",644+50,130+60,d == 1)){ d = 1; p = true; } if(bot("普通",644+100,130+60,d == 2)){ d = 2; p = true; } Text("2x",648,125+120); if(bot("ON",644,130+120,x2)){ x2 = true; p = true; } if(bot("OFF",644+50,130+120,!x2)){ x2 = false; p = true; } //if(bot("V3",644+50,130,v == 2)){ //v = 2; //p = true; //} if(p)pass = passa; } }
conv1(バージョン1に圧縮256色にするプログラム)
int filesize(PImage img) { int bh = (img.width*img.height)+4; return bh; } byte[] con(PImage img) { int bh = 0; bh = (img.width*img.height)+4; byte[] bytes = new byte[bh]; char xs = char(img.width); char ys = char(img.height); println("変換やりまーす"); println("画像サイズ:"+xs+"x"+ys); //上位 8bit を送出 byte up = byte(xs >> 8); bytes[0] = up; byte down = byte(xs & 255); bytes[1] = down; ; up = byte(ys >> 8); bytes[2] = up; down = byte(ys & 255); bytes[3] = down; ; int f = 0; boolean ffA = false; for (int y = 0; y < ys; y++) { ffA = !ffA; boolean ffa = ffA; boolean ffaa = false; for (int x = 0; x < xs; x++) { int F = 8; if (ffa)F = -8; if(d == 0)F = 0; if(d == 1)F /= 2; int R = int(( red(img.get(x, y)) +F)/34.1333333 ); int G = int(( green(img.get(x, y))+F)/34.1333333 ); F *= 2; int B = int(( blue(img.get(x, y) )+F)/73.1428571 ); if (R > 7)R = 7; if (G > 7)G = 7; if (B > 3)B = 3; if (R < 0)R = 0; if (G < 0)G = 0; if (B < 0)B = 0; String r = binary(R, 3); String g = binary(G, 3); String b = binary(B, 2); String rgb = r+g+b; //byte in = byte(unbinary(rgb)); byte in = 0; in = byte(in | (R<<5)); in = byte(in | (G<<2)); in = byte(in | (B<<0)); bytes[4+f] = in; //println(r,g,b); // f++; ffa = !ffa; } } return bytes; } ; PImage ucon(byte[] img) { boolean unload = false; PImage out = null; PGraphics pg = null; if (img != null) { int mask = 0b10000000; int umask = 0b01111111; if((img[0]&mask) != 0){ println("新型"); unload = true; } img[0] = byte(img[0] & umask); if (!unload) { for (int i = 0; i < img.length; i++) { img[i] ^= mask; } int xs = ((img[0]+128)*256)+(img[1]+128); int ys = ((img[2]+128)*256)+(img[3]+128); println(xs, ys); pg = createGraphics(xs, ys); pg.beginDraw(); pg.loadPixels(); for (int i = 0; i < pg.pixels.length; i++) { int in = int(img[i+4]+128); //String k = binary(int(img[i+4]+128), 8); //String R = k.substring(0, 3); //String G = k.substring(3, 6); //String B = k.substring(6, 8); //float r = unbinary(R)*36.5714285; //float g = unbinary(G)*36.5714285; //float b = unbinary(B)*85.3333333; // int R = 0b11100000; int G = 0b00011100; int B = 0b00000011; float r = (in&R)>>5; float g = (in&G)>>2; float b = (in&B); r *= 34.1333333; g *= 34.1333333; b *= 73.1428571; //r = 255-r; //g = 255-g; //b = 255-b; //println(r, g, b); pg.pixels[i] = color(r, g, b, 256); } pg.updatePixels(); pg.endDraw(); //pg.save(pass+".png"); } } if(pg != null)out = pg.get(); if(unload)out = ucon2(img); return out; }
conv2(バージョン2、65500色にするプログラム)
int filesize2(PImage img) { int bh = (img.width*img.height*2)+4; return bh; } byte[] con2(PImage img) { int bh = 0; bh = (img.width*img.height*2)+4; byte[] bytes = new byte[bh]; char xs = char(img.width); char ys = char(img.height); println("変換やりまーす"); println("画像サイズ:"+xs+"x"+ys); //上位 8bit を送出 byte up = byte(xs >> 8); int mask = 0b10000000; bytes[0] = byte(up|mask); byte down = byte(xs & 255); bytes[1] = down; ; up = byte(ys >> 8); bytes[2] = up; down = byte(ys & 255); bytes[3] = down; ; int f = 0; boolean ffA = false; for (int y = 0; y < ys; y++) { ffA = !ffA; boolean ffa = ffA; for (int x = 0; x < xs; x++) { int F = 2; if (ffa)F = -2; if(d == 0)F = 0; if(d == 1)F /= 2; int R = int(( red(img.get(x, y)) +F)/8.12698413 ); int B = int(( blue(img.get(x, y) )+F)/8.12698413 ); F /= 2; int G = int(( green(img.get(x, y))+F)/4.03149606 ); if (R > 31)R = 31; if (G > 63)G = 63; if (B > 31)B = 31; if (R < 0)R = 0; if (G < 0)G = 0; if (B < 0)B = 0; String r = binary(R, 5); String g = binary(G, 6); String b = binary(B, 5); String rgb = r+g+b; //println(rgb); //byte in = byte(unbinary(rgb)); //rrrrrggggggbbbbb // char rgba = 0; rgba = char(rgba | (R<<11)); rgba = char(rgba | (G<<5)); rgba = char(rgba | (B<<0)); ; //rgba = char(rgba^mask); ; byte upa = byte(rgba >> 8); byte downa = byte(rgba & 255); ; bytes[4+(f*2)+0] = upa; bytes[4+(f*2)+1] = downa; //println(r,g,b); f++; ffa = !ffa; } } return bytes; } ; PImage ucon2(byte[] img) { PImage out = null; PGraphics pg = null; if (img != null) { int mask = 0b10000000; int umask = 0b01111111; img[0] = byte(img[0] & umask); for (int i = 0; i < img.length; i++) { img[i] ^= mask; } int xs = ((img[0]+128)*256)+(img[1]+128); int ys = ((img[2]+128)*256)+(img[3]+128); println(xs, ys); pg = createGraphics(xs, ys); pg.beginDraw(); pg.loadPixels(); for (int i = 0; i < pg.pixels.length; i++) { int in = int(img[(i*2)+4]+128); int ina = int(img[(i*2)+5]+128); in = ina+(in*256); //String k = binary(int(img[i+4]+128), 8); //String R = k.substring(0, 3); //String G = k.substring(3, 6); //String B = k.substring(6, 8); //float r = unbinary(R)*36.5714285; //float g = unbinary(G)*36.5714285; //float b = unbinary(B)*85.3333333; // int R = 0b1111100000000000; int G = 0b0000011111100000; int B = 0b0000000000011111; float r = (in&R)>>11; float g = (in&G)>>5; float b = (in&B); r *= 8.12698413; g *= 4.03149606; b *= 8.12698413; //r = 255-r; //g = 255-g; //b = 255-b; //println(r, g, b); pg.pixels[i] = color(r, g, b); } pg.updatePixels(); pg.endDraw(); } out = pg.get(); return out; }
dd(ドラッグ&ドロップのためのプログラム)
import java.awt.datatransfer.*; import java.awt.dnd.*; import java.io.File; import java.io.IOException; import java.awt.Component; import java.util.List; String pass = null; DropTarget dropTarget; Component component; void dragDropFile() { component = (Component)this.surface.getNative(); dropTarget = new DropTarget(component, new DropTargetListener() { public void dragEnter(DropTargetDragEvent dtde) { } public void dragOver(DropTargetDragEvent dtde) { } public void dropActionChanged(DropTargetDragEvent dtde) { } public void dragExit(DropTargetEvent dte) { } public void drop(DropTargetDropEvent dtde) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Transferable trans = dtde.getTransferable(); List<File> fileNameList = null; if (trans.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { try { fileNameList = (List<File>) trans.getTransferData(DataFlavor.javaFileListFlavor); } catch (UnsupportedFlavorException ex) { println(ex); } catch (IOException ex) { println(ex); } } if (fileNameList == null) return; for (File f : fileNameList) { println(f.getAbsolutePath()); pass = f.getAbsolutePath(); } } } ); }
gui(グラフィカルuserインターフェースの略。ボタンのプログラム)
PImage _2x(PImage in) { PGraphics pg = createGraphics(in.width*2, in.height*2); pg.noSmooth(); pg.beginDraw(); pg.noSmooth(); pg.scale(2); pg.image(in, 0, 0); pg.endDraw(); return pg.get(); } PImage _n2x(PImage in) { PGraphics pg = createGraphics(in.width/2, in.height/2); pg.noSmooth(); pg.beginDraw(); pg.noSmooth(); pg.scale(0.5); pg.image(in, 0, 0); pg.endDraw(); return pg.get(); } boolean bot(String t, float x, float y, boolean f) { int w = 50; int h = 40-8; //w = int(textWidth(t)+16)-8; x += 2; y += 2; ; w -= 2; h -= 2; x += 2; y += 2; boolean a = false; if (x <= mouseX && x+w >= mouseX) { if (y <= mouseY && y+h >= mouseY) { a = true; } } w += 2; h += 2; x -= 2; y -= 2; int ofx = 0; int ofy = -4; ; w -= 2; h -= 2; x += 3; y += 4; ; fill(255, 64); rect(x, y, w, h); if (f)rect(x, y, w, h); fill(255); text(t, x+(w/2)-(textWidth(t)/2)+ofx, h+2+y-7+ofy); if (!mousePressed)a = false; return a; }
データの予測容量を計算して表示できるようにしました!!!
I made it possible to calculate and display the predicted capacity of the data
Download zip here↓
操作動画は、こちら↓ on YouTube