Git リポジトリ化
@@ -0,0 +1,287 @@
|
|||||||
|
/**************************************************/
|
||||||
|
/* */
|
||||||
|
/* MedianCut.js */
|
||||||
|
/* v0.88 */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2016 Takeshi Okamoto (Japan) */
|
||||||
|
/* */
|
||||||
|
/* Released under the MIT license */
|
||||||
|
/* https://github.com/TakeshiOkamoto/ */
|
||||||
|
/* */
|
||||||
|
/* Date: 2016-12-14 */
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Generic Function
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 画像のカラー情報の取得
|
||||||
|
function getColorInfo(imagedata){
|
||||||
|
var height = imagedata.height;
|
||||||
|
var width = imagedata.width;
|
||||||
|
var raw = imagedata.data;
|
||||||
|
|
||||||
|
// 使用色/使用回数(面積)を取得
|
||||||
|
var cnt = 0;
|
||||||
|
var uses_colors = new Object;
|
||||||
|
|
||||||
|
for(var i = 0; i< height;i++){
|
||||||
|
for(var j = 0; j< width;j++){
|
||||||
|
var key = raw[cnt] + ',' +
|
||||||
|
raw[cnt+1] + ',' +
|
||||||
|
raw[cnt+2] ;
|
||||||
|
if (!uses_colors[key])
|
||||||
|
uses_colors[key] = 1;
|
||||||
|
else
|
||||||
|
uses_colors[key] += 1;
|
||||||
|
|
||||||
|
cnt = cnt + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 連想配列を配列へ設定
|
||||||
|
var rgb;
|
||||||
|
var colors = new Array();
|
||||||
|
for (var key in uses_colors) {
|
||||||
|
rgb = key.split(",");
|
||||||
|
colors[colors.length] = {'r':parseInt(rgb[0],10),
|
||||||
|
'g':parseInt(rgb[1],10),
|
||||||
|
'b':parseInt(rgb[2],10),
|
||||||
|
'uses':uses_colors[key]}; // 使用数
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Generic Class
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// TMedianCut
|
||||||
|
// ---------------------
|
||||||
|
// imagedata : 減色するImageDataオブジェクト
|
||||||
|
// colors : getColorInfo()で取得したカラー情報
|
||||||
|
function TMedianCut(imagedata,colors) {
|
||||||
|
|
||||||
|
this.raw = imagedata.data;
|
||||||
|
this.width = imagedata.width;
|
||||||
|
this.height = imagedata.height;
|
||||||
|
this.msg = '';
|
||||||
|
this.colors = colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// TMedianCut.Method
|
||||||
|
// ---------------------
|
||||||
|
TMedianCut.prototype = {
|
||||||
|
|
||||||
|
// プロパティの設定
|
||||||
|
_setProperty : function (color){
|
||||||
|
var total = 0;
|
||||||
|
var maxR = 0, maxG = 0, maxB = 0;
|
||||||
|
var minR = 255, minG = 255, minB = 255;
|
||||||
|
|
||||||
|
// 立方体の1辺の長さ
|
||||||
|
for(var i = 0; i < color.length;i++){
|
||||||
|
|
||||||
|
if (color[i].rgb.r > maxR) maxR = color[i].rgb.r ;
|
||||||
|
if (color[i].rgb.g > maxG) maxG = color[i].rgb.g ;
|
||||||
|
if (color[i].rgb.b > maxB) maxB = color[i].rgb.b ;
|
||||||
|
|
||||||
|
if (color[i].rgb.r < minR) minR = color[i].rgb.r ;
|
||||||
|
if (color[i].rgb.g < minG) minG = color[i].rgb.g ;
|
||||||
|
if (color[i].rgb.b < minB) minB = color[i].rgb.b ;
|
||||||
|
|
||||||
|
// キューブで使用している面積
|
||||||
|
total += color[i].rgb.uses;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dr = (maxR - minR)*1.2;
|
||||||
|
var dg = (maxG - minG)*1.2;
|
||||||
|
var db = (maxB - minB);
|
||||||
|
|
||||||
|
// 同一の場合はrを優先する
|
||||||
|
var colortype = 'r';
|
||||||
|
|
||||||
|
// r
|
||||||
|
if (dr > dg && dr > db){
|
||||||
|
colortype = 'r';
|
||||||
|
}
|
||||||
|
|
||||||
|
// g
|
||||||
|
if (dg > dr && dg > db){
|
||||||
|
colortype = 'g';
|
||||||
|
}
|
||||||
|
|
||||||
|
// b
|
||||||
|
if (db > dr && db > dg){
|
||||||
|
colortype = 'b';
|
||||||
|
}
|
||||||
|
|
||||||
|
return { 'color' : color, // キューブの各色情報
|
||||||
|
'total' : total, // キューブの総面積(総色数)
|
||||||
|
'type' : colortype,// キューブの種類(R/G/B)
|
||||||
|
// キューブの体積用 'volume': dr * dg * db
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// メディアンカット
|
||||||
|
_MedianCut : function(cubes,colorsize){
|
||||||
|
var count = 0;
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
|
// 面積(色数)が最大のキューブを選択
|
||||||
|
for(var i = 0; i < cubes.length;i++){
|
||||||
|
if(cubes[i].total > count){
|
||||||
|
// 1点は除く
|
||||||
|
if (cubes[i].color.length != 1){
|
||||||
|
index = i;
|
||||||
|
count = cubes[i].total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 体積が最大のキューブを選択
|
||||||
|
//if(cubes[index].color.length == 1){
|
||||||
|
//
|
||||||
|
// count =0; index =0;
|
||||||
|
//
|
||||||
|
// for(var i = 0; i < cubes.length;i++){
|
||||||
|
// if(cubes[i].volume > count){
|
||||||
|
// index = i;
|
||||||
|
// count = cubes[i].volume;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
if (cubes[index].total == 1){
|
||||||
|
// Cube could not be split.
|
||||||
|
this.msg += colorsize + '色までキューブを分割できませんでした。\n';
|
||||||
|
return cubes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cubes[index].color.length == 1){
|
||||||
|
// Cube could not be split.
|
||||||
|
this.msg += colorsize + '色までキューブを分割できませんでした。\n';
|
||||||
|
return cubes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// メディアン由来の中央値を算出する
|
||||||
|
var colortype = cubes[index].type;
|
||||||
|
cubes[index].color.sort(function(a,b){
|
||||||
|
if(a.rgb[colortype] < b.rgb[colortype] ) return -1;
|
||||||
|
if(a.rgb[colortype] > b.rgb[colortype] ) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
split_border = Math.floor((cubes[index].color.length+1)/2);
|
||||||
|
|
||||||
|
// 分割の開始
|
||||||
|
var split1 = new Array;
|
||||||
|
var split2 = new Array;
|
||||||
|
for(var i = 0; i < cubes[index].color.length;i++){
|
||||||
|
if (i < split_border){
|
||||||
|
split1[split1.length] = cubes[index].color[i];
|
||||||
|
}else{
|
||||||
|
split2[split2.length] = cubes[index].color[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// プロパティの設定
|
||||||
|
split1 = this._setProperty(split1);
|
||||||
|
split2 = this._setProperty(split2);
|
||||||
|
|
||||||
|
// キューブ配列の再編成
|
||||||
|
var result = new Array();
|
||||||
|
for(var i = 0; i < cubes.length;i++){
|
||||||
|
if (i != index){
|
||||||
|
result[result.length] = cubes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[result.length] = split1;
|
||||||
|
result[result.length] = split2;
|
||||||
|
|
||||||
|
if (result.length < colorsize){
|
||||||
|
return this._MedianCut(result,colorsize);
|
||||||
|
}else{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 減色の実行
|
||||||
|
// colorsize : 最大何色まで減色するかの色数(2- 256)
|
||||||
|
// update : true ピクセルデータを更新 false 更新しない
|
||||||
|
run : function(colorsize,update){
|
||||||
|
|
||||||
|
if (this.colors.length <= colorsize){
|
||||||
|
// It has already been reduced color.
|
||||||
|
this.msg = '既に'+ this.colors.length +'色に減色されています。\n';
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1個目のキューブの作成
|
||||||
|
var plane = new Array;
|
||||||
|
for(var i = 0; i < this.colors.length;i++){
|
||||||
|
plane[plane.length] = {'rgb': this.colors[i]};
|
||||||
|
}
|
||||||
|
|
||||||
|
var dummy = new Array();
|
||||||
|
dummy[0] = this._setProperty(plane);
|
||||||
|
|
||||||
|
// キューブの分割
|
||||||
|
var cubes = this._MedianCut(dummy,colorsize);
|
||||||
|
|
||||||
|
// キューブ毎に代表色(重み係数による平均)を算出する
|
||||||
|
var rep_color = new Array();
|
||||||
|
for(var i = 0; i < cubes.length;i++){
|
||||||
|
var count = 0;
|
||||||
|
var r =0,g=0,b=0;
|
||||||
|
for(var j = 0; j < cubes[i].color.length;j++){
|
||||||
|
r += cubes[i].color[j].rgb.r * cubes[i].color[j].rgb.uses;
|
||||||
|
g += cubes[i].color[j].rgb.g * cubes[i].color[j].rgb.uses;
|
||||||
|
b += cubes[i].color[j].rgb.b * cubes[i].color[j].rgb.uses;
|
||||||
|
count += cubes[i].color[j].rgb.uses;
|
||||||
|
}
|
||||||
|
rep_color[i] = {'r': Math.round(r/count),
|
||||||
|
'g': Math.round(g/count),
|
||||||
|
'b': Math.round(b/count)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 代表色の保存
|
||||||
|
this.rep_color = rep_color;
|
||||||
|
|
||||||
|
// ピクセルデータの更新
|
||||||
|
if (update) {
|
||||||
|
|
||||||
|
// ピクセルデータ設定用の連想配列(高速化用)
|
||||||
|
var pixels = new Object;
|
||||||
|
for(var i = 0; i < cubes.length;i++){
|
||||||
|
for(var j = 0; j < cubes[i].color.length;j++){
|
||||||
|
pixels[cubes[i].color[j].rgb.r + ',' +
|
||||||
|
cubes[i].color[j].rgb.g + ',' +
|
||||||
|
cubes[i].color[j].rgb.b] = {'r': rep_color[i].r,
|
||||||
|
'g': rep_color[i].g,
|
||||||
|
'b': rep_color[i].b};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// データの設定
|
||||||
|
var key,cnt =0;
|
||||||
|
for(var i = 0; i< this.height;i++){
|
||||||
|
for(var j = 0; j< this.width;j++){
|
||||||
|
|
||||||
|
key = this.raw[cnt] + ',' +
|
||||||
|
this.raw[cnt+1] + ',' +
|
||||||
|
this.raw[cnt+2];
|
||||||
|
|
||||||
|
this.raw[cnt] = pixels[key].r;
|
||||||
|
this.raw[cnt+1] = pixels[key].g;
|
||||||
|
this.raw[cnt+2] = pixels[key].b;
|
||||||
|
|
||||||
|
cnt = cnt + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
define ('SAVE_DIR', 'draft/');
|
||||||
|
|
||||||
|
$json = getParamJSON ();
|
||||||
|
|
||||||
|
if (!(isset ($json['data'])))
|
||||||
|
{
|
||||||
|
sendResult (false, 'Empty query Parameter: data');
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(preg_match ('/^data:image\/png;base64,/', $json['data'])))
|
||||||
|
{
|
||||||
|
sendResult (false, 'Not Allow data type: data');
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $json['data'];
|
||||||
|
$data = str_replace ('data:image/png;base64,', '', $data);
|
||||||
|
$data = str_replace (' ', '+', $data);
|
||||||
|
$image = base64_decode ($data);
|
||||||
|
|
||||||
|
$file = sprintf ('%s.png', $_GET['id']);
|
||||||
|
$result = file_put_contents (SAVE_DIR . $file, $image, LOCK_EX);
|
||||||
|
|
||||||
|
setcookie ('backup', $file, time () + 60 * 60 * 24 * 30);
|
||||||
|
|
||||||
|
|
||||||
|
function
|
||||||
|
getParamJSON ()
|
||||||
|
{
|
||||||
|
$buff = file_get_contents ('php://input');
|
||||||
|
$json = json_decode ($buff, true);
|
||||||
|
|
||||||
|
return ($json);
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
sendResult ($status, $data)
|
||||||
|
{
|
||||||
|
header ('Access-Control-Allow-Origin: *');
|
||||||
|
header ('Access-Control-Allow-Headers: *');
|
||||||
|
|
||||||
|
echo json_encode(["status" => $status,
|
||||||
|
"result" => $data]);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
require "${_SERVER['DOCUMENT_ROOT']}/database.php";
|
||||||
|
|
||||||
|
|
||||||
|
$mysqli = set_mysql ('miteruzo_bbs');
|
||||||
|
|
||||||
|
$mysqli -> set_charset ('utf8');
|
||||||
|
|
||||||
|
$thread = $_GET['thread'];
|
||||||
|
$id = $_GET['id'];
|
||||||
|
$pass = $_GET['pass'];
|
||||||
|
|
||||||
|
if ($result = $mysqli -> query ("
|
||||||
|
SELECT
|
||||||
|
pass, image
|
||||||
|
FROM
|
||||||
|
responses
|
||||||
|
WHERE
|
||||||
|
(thread_id = {$_GET['thread']}) AND (response_id = {$_GET['id']})")):
|
||||||
|
$row = $result -> fetch_assoc ();
|
||||||
|
|
||||||
|
if ($_GET['pass'] == $row['pass']):
|
||||||
|
$mysqli -> query ("
|
||||||
|
UPDATE
|
||||||
|
responses
|
||||||
|
SET
|
||||||
|
deleted = 1
|
||||||
|
WHERE
|
||||||
|
(thread_id = $thread) AND (response_id = $id)");
|
||||||
|
|
||||||
|
echo "消しましたぁ!!<br /><br /><img style='border: solid 1px' src='image/{$row['image']}' />";
|
||||||
|
else:
|
||||||
|
echo '残念.<br />削除用パスワードが違います.';
|
||||||
|
endif;
|
||||||
|
|
||||||
|
echo "<br /><br />5 秒後に元のページに戻ります.<br /><br /><a href='./?thread=$thread#$id'>戻らない場合はこちら</a><script>setTimeout (function () {window.location.href = `./?thread=$thread#$id`}, 5000)</script>";
|
||||||
|
endif;
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
require "${_SERVER['DOCUMENT_ROOT']}/database.php";
|
||||||
|
|
||||||
|
|
||||||
|
$mysqli = set_mysql ('miteruzo_bbs');
|
||||||
|
|
||||||
|
$mysqli -> set_charset ('utf8');
|
||||||
|
|
||||||
|
$thread = $_GET['thread'];
|
||||||
|
$id = $_GET['id'];
|
||||||
|
$pass = $_GET['pass'];
|
||||||
|
|
||||||
|
if ($result = $mysqli -> query ("
|
||||||
|
SELECT
|
||||||
|
pass
|
||||||
|
FROM
|
||||||
|
responses
|
||||||
|
WHERE
|
||||||
|
(thread_id = {$_GET['thread']}) AND (response_id = {$_GET['id']})")):
|
||||||
|
$row = $result -> fetch_assoc ();
|
||||||
|
|
||||||
|
if ($_GET['pass'] == $row['pass']):
|
||||||
|
else:
|
||||||
|
echo "残念.\n削除用パスワードが違います.<script>setTimeout (function () {window.location.href = `./?thread=$thread`}, 5000)</script>";
|
||||||
|
endif;
|
||||||
|
endif;
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 256 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 21 KiB |