• 27-04-2025, 13:13:24
    #1
    Üyeliği durduruldu

    Link: https://saitama.net.tr/filtre/

    <!DOCTYPE html>
    <html lang="tr-TR">
    <head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>Görüntü Renk Düzeltme Özel Filtreler</title>
    <link rel="stylesheet"
          href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap">
    
    <style>
    /* ===== Global Renkler (Modern Stil) ===== */
    :root{
      /* Ana Renkler */
      --primary:#1A73E8;
      --primary-hover:#1967D2;
      --primary-light:rgba(26,115,232,0.08);
      --success:#34A853;
      --success-hover:#2E9249;
      --danger:#EA4335;
      --warning:#FBBC05;
      
      /* Nötr Renkler */
      --bg:#F8F9FA;
      --card:#FFFFFF;
      --border:rgba(0,0,0,0.12);
      --txt:#202124;
      --txt-secondary:#5F6368;
      --txt-disabled:#9AA0A6;
      
      /* Gölgeler */
      --shadow-sm:0 1px 2px rgba(0,0,0,0.05);
      --shadow:0 2px 6px rgba(0,0,0,0.08);
      --shadow-lg:0 4px 12px rgba(0,0,0,0.12);
      
      /* Köşe Radyusu */
      --radius-sm:4px;
      --radius:8px;
      --radius-lg:12px;
      --radius-xl:16px;
      
      /* Boşluklar */
      --space-xxs:2px;
      --space-xs:4px;
      --space-sm:8px;
      --space-md:16px;
      --space-lg:24px;
      --space-xl:32px;
      --space-xxl:48px;
      
      /* Animasyonlar */
      --transition-fast:0.15s ease-out;
      --transition:0.25s ease-out;
    }
    
    @media(prefers-color-scheme:dark){
      :root{
        --primary:#8AB4F8;
        --primary-hover:#9CC3FF;
        --primary-light:rgba(138,180,248,0.08);
        --success:#81C995;
        --success-hover:#8FD5A3;
        --danger:#F28B82;
        --warning:#FDD663;
        
        --bg:#202124;
        --card:#2D2F31;
        --border:rgba(255,255,255,0.12);
        --txt:#E8EAED;
        --txt-secondary:#BBBEC3;
        --txt-disabled:#80868B;
        
        --shadow-sm:0 1px 2px rgba(0,0,0,0.25);
        --shadow:0 2px 6px rgba(0,0,0,0.35);
        --shadow-lg:0 4px 12px rgba(0,0,0,0.45);
      }
    }
    
    * {
      margin:0;
      padding:0;
      box-sizing:border-box;
      -webkit-tap-highlight-color:transparent;
    }
    
    body {
      font-family:'Inter',-apple-system,BlinkMacSystemFont,'SF Pro Text',
      'Helvetica Neue',sans-serif;
      background:var(--bg);
      color:var(--txt);
      line-height:1.5;
      -webkit-font-smoothing:antialiased;
      padding:env(safe-area-inset-top) env(safe-area-inset-right)
              env(safe-area-inset-bottom) env(safe-area-inset-left);
      transition:background var(--transition);
    }
    
    .container {
      max-width:1200px;
      margin:0 auto;
      padding:var(--space-md);
    }
    
    /* Başlık */
    .header {
      text-align:center;
      margin-bottom:var(--space-xl);
      padding:var(--space-lg) 0 var(--space-xl);
    }
    
    .header h1 {
      font-size:2.5rem;
      font-weight:700;
      margin-bottom:var(--space-sm);
      letter-spacing:-0.02em;
      background:linear-gradient(135deg, var(--primary), var(--success));
      -webkit-background-clip:text;
      background-clip:text;
      color:transparent;
    }
    
    .header p {
      font-size:1.125rem;
      color:var(--txt-secondary);
      max-width:600px;
      margin:0 auto;
      opacity:0.9;
    }
    
    /* Kart */
    .card {
      background:var(--card);
      border-radius:var(--radius-lg);
      box-shadow:var(--shadow-lg);
      overflow:hidden;
      margin-bottom:var(--space-xl);
      border:1px solid var(--border);
      backdrop-filter:blur(20px);
      -webkit-backdrop-filter:blur(20px);
      transition:box-shadow var(--transition), background var(--transition), border var(--transition);
    }
    
    .card:hover {
      box-shadow:var(--shadow-lg);
    }
    
    /* Karşılaştırma Alanı */
    .compare-box {
      position:relative;
      width:100%;
      min-height:280px;
      overflow:hidden;
      background:#111;
      border-radius:var(--radius-lg) var(--radius-lg) 0 0;
    }
    
    .compare-img {
      position:absolute;
      top:0;
      left:0;
      width:100%;
      height:100%;
      object-fit:contain;
      opacity:0;
      transition:opacity 0.3s ease;
    }
    
    .compare-img.loaded {
      opacity:1;
    }
    
    .compare-img.corr {
      clip-path:inset(0 0 0 50%);
    }
    
    .img-labels {
      position:absolute;
      top:var(--space-md);
      left:0;
      width:100%;
      display:flex;
      justify-content:space-between;
      padding:0 var(--space-md);
      z-index:5;
      pointer-events:none;
    }
    
    .img-tag {
      font-size:0.813rem;
      font-weight:600;
      color:#fff;
      background:rgba(0,0,0,0.6);
      padding:8px 14px;
      border-radius:var(--radius-xl);
      display:flex;
      align-items:center;
      gap:6px;
      backdrop-filter:blur(4px);
      -webkit-backdrop-filter:blur(4px);
      box-shadow:0 2px 8px rgba(0,0,0,0.2);
      transition:transform var(--transition-fast), background var(--transition-fast);
    }
    
    .img-tag:hover {
      transform:translateY(-2px);
      background:rgba(0,0,0,0.75);
    }
    
    .img-tag::before {
      content:"";
      display:inline-block;
      width:8px;
      height:8px;
      border-radius:50%;
    }
    
    .img-tag.orig::before {
      background:var(--danger);
    }
    
    .img-tag.corr::before {
      background:var(--success);
    }
    
    .placeholder {
      position:absolute;
      inset:0;
      display:flex;
      flex-direction:column;
      align-items:center;
      justify-content:center;
      color:var(--txt-secondary);
      background:rgba(0,0,0,0.05);
      transition:opacity 0.3s ease;
    }
    
    .placeholder svg {
      width:52px;
      height:52px;
      margin-bottom:var(--space-md);
      opacity:0.6;
      fill:none;
      stroke:currentColor;
      stroke-width:1.5;
      stroke-linecap:round;
      stroke-linejoin:round;
    }
    
    .placeholder span {
      font-size:0.938rem;
      font-weight:500;
    }
    
    /* Kaydırıcı */
    .slider {
      position:absolute;
      top:0;
      left:50%;
      transform:translateX(-50%);
      width:44px;
      height:100%;
      cursor:col-resize;
      z-index:6;
      display:flex;
      align-items:center;
      justify-content:center;
      transition:left var(--transition-fast);
    }
    
    .slider-line {
      position:absolute;
      width:2px;
      height:100%;
      background:#fff;
      box-shadow:0 0 8px rgba(0,0,0,0.5);
    }
    
    .slider-btn {
      width:38px;
      height:38px;
      border-radius:50%;
      background:#fff;
      box-shadow:0 2px 12px rgba(0,0,0,0.5);
      position:relative;
      display:flex;
      align-items:center;
      justify-content:center;
      transition:transform var(--transition-fast);
    }
    
    .slider:hover .slider-btn {
      transform:scale(1.1);
    }
    
    .slider-btn::before, .slider-btn::after {
      content:"";
      position:absolute;
      width:10px;
      height:10px;
      border:solid 2px #555;
      border-width:0 0 2px 2px;
    }
    
    .slider-btn::before {
      transform:translateX(-4px) rotate(45deg);
    }
    
    .slider-btn::after {
      transform:translateX(4px) rotate(225deg);
    }
    
    /* Kontrol Paneli */
    .controls {
      padding:var(--space-xl);
    }
    
    .section-title {
      font-size:1.125rem;
      font-weight:600;
      margin-bottom:var(--space-md);
      color:var(--txt);
      display:flex;
      align-items:center;
      gap:var(--space-xs);
    }
    
    .section-title svg {
      width:20px;
      height:20px;
      stroke:var(--primary);
    }
    
    .input-set {
      display:flex;
      gap:var(--space-md);
      margin-bottom:var(--space-lg);
    }
    
    .file-wrap {
      flex:1;
      position:relative;
    }
    
    .file-hidden {
      position:absolute;
      inset:0;
      opacity:0;
      cursor:pointer;
      z-index:2;
    }
    
    .btn, .file-vis {
      height:48px;
      border:none;
      border-radius:var(--radius);
      font-size:0.938rem;
      font-weight:600;
      cursor:pointer;
      transition:all var(--transition-fast);
      padding:0 var(--space-md);
      display:flex;
      align-items:center;
      justify-content:center;
      gap:var(--space-xs);
    }
    
    .file-vis {
      width:100%;
      background:var(--primary);
      color:#fff;
    }
    
    .file-vis:hover {
      background:var(--primary-hover);
      transform:translateY(-2px);
      box-shadow:var(--shadow);
    }
    
    .btn.grey {
      background:var(--bg);
      color:var(--txt);
      border:1px solid var(--border);
    }
    
    .btn.grey:hover {
      background:var(--card);
      transform:translateY(-2px);
      box-shadow:var(--shadow);
    }
    
    .btn.blue {
      background:var(--primary);
      color:#fff;
    }
    
    .btn.blue:hover {
      background:var(--primary-hover);
      transform:translateY(-2px);
      box-shadow:var(--shadow);
    }
    
    .btn.green {
      background:var(--success);
      color:#fff;
    }
    
    .btn.green:hover {
      background:var(--success-hover);
      transform:translateY(-2px);
      box-shadow:var(--shadow);
    }
    
    .btn-icon {
      width:20px;
      height:20px;
      stroke:currentColor;
      fill:none;
      stroke-width:2;
      stroke-linecap:round;
      stroke-linejoin:round;
    }
    
    /* Sürgü Kontrolleri */
    .adjustment-section {
      margin-top:var(--space-xl);
      margin-bottom:var(--space-lg);
    }
    
    .range-set {
      margin-bottom:var(--space-md);
      position:relative;
    }
    
    .range-head {
      display:flex;
      justify-content:space-between;
      align-items:center;
      margin-bottom:var(--space-xs);
    }
    
    .range-head span:first-child {
      font-weight:500;
      font-size:0.938rem;
    }
    
    .range-head span:last-child {
      font-variant-numeric:tabular-nums;
      color:var(--txt-secondary);
      font-size:0.875rem;
      background:var(--primary-light);
      padding:2px 8px;
      border-radius:var(--radius-sm);
      transition:background 0.2s;
    }
    
    .range {
      width:100%;
      height:5px;
      -webkit-appearance:none;
      background:var(--border);
      border-radius:var(--radius-xl);
      outline:none;
      margin:var(--space-sm) 0;
      cursor:pointer;
    }
    
    .range::-webkit-slider-thumb {
      -webkit-appearance:none;
      width:18px;
      height:18px;
      border-radius:50%;
      background:var(--primary);
      box-shadow:0 1px 4px rgba(0,0,0,0.25);
      cursor:pointer;
      transition:transform 0.2s;
    }
    
    .range::-webkit-slider-thumb:hover {
      transform:scale(1.2);
    }
    
    .range::-moz-range-thumb {
      width:18px;
      height:18px;
      border-radius:50%;
      background:var(--primary);
      box-shadow:0 1px 4px rgba(0,0,0,0.25);
      cursor:pointer;
      border:none;
      transition:transform 0.2s;
    }
    
    .range::-moz-range-thumb:hover {
      transform:scale(1.2);
    }
    
    .btn-group {
      display:flex;
      gap:var(--space-md);
      margin-top:var(--space-xl);
      flex-wrap:wrap;
    }
    
    /* Filtre Butonları */
    .filter-btn-group {
      display:flex;
      gap:var(--space-sm);
      margin-bottom:var(--space-lg);
      flex-wrap:wrap;
    }
    
    .filter-btn {
      padding:8px 16px;
      background:var(--bg);
      color:var(--txt);
      font-size:0.875rem;
      font-weight:500;
      border-radius:var(--radius);
      border:1px solid var(--border);
      cursor:pointer;
      transition:all var(--transition-fast);
    }
    
    .filter-btn:hover {
      transform:translateY(-2px);
      box-shadow:var(--shadow);
    }
    
    .filter-btn.active {
      background:var(--primary);
      color:#fff;
      border-color:var(--primary);
    }
    
    /* Alt Bilgi */
    .footer {
      text-align:center;
      margin-top:var(--space-xxl);
      padding:var(--space-lg) var(--space-md);
      font-size:0.813rem;
      color:var(--txt-secondary);
    }
    
    .footer a {
      color:var(--primary);
      text-decoration:none;
    }
    
    .footer a:hover {
      text-decoration:underline;
    }
    
    @media(max-width:768px) {
      .header h1 {
        font-size:1.75rem;
      }
      
      .header p {
        font-size:0.938rem;
      }
      
      .input-set {
        flex-direction:column;
      }
      
      .controls {
        padding:var(--space-lg);
      }
      
      .btn, .file-vis {
        height:44px;
      }
      
      .btn-group {
        flex-direction:column;
      }
      
      .btn-group .btn {
        width:100%;
      }
    }
    </style>
    </head>
    
    <body>
    <div class="container">
      <div class="header">
        <h1>Görüntü Renk Düzeltme ve Filtreler</h1>
        <p>Akıllı renk sapması düzeltme, gerçek renkleri yenileme ve özel sanatsal filtre efektleri</p>
      </div>
    
      <!-- ==================== Karşılaştırma Görüntüsü ==================== -->
      <div class="card">
        <div class="compare-box" id="compareBox">
          <div class="img-labels">
            <div class="img-tag orig">Orijinal</div>
            <div class="img-tag corr">İşlenmiş</div>
          </div>
    
          <img id="imgOrig" class="compare-img"/>
          <div id="phOrig" class="placeholder">
            <!-- Kamera İkonu -->
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
              <circle cx="8.5" cy="8.5" r="1.5"/>
              <polyline points="21 15 16 10 5 21"/>
            </svg>
            <span>Lütfen bir görüntü seçin veya yapıştırın</span>
          </div>
    
          <!-- Düzeltme / Filtre Sonucu -->
          <img id="imgCorr" class="compare-img corr" style="display:none">
          <canvas id="canvasCorr" class="compare-img corr" style="display:none"></canvas>
          <div id="phCorr" class="placeholder">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
            </svg>
            <span>"Otomatik Düzelt" düğmesine tıklayın</span>
          </div>
    
          <!-- Kaydırıcı -->
          <div class="slider" id="splitSlider">
            <div class="slider-line"></div>
            <div class="slider-btn"></div>
          </div>
        </div>
      </div>
    
      <!-- ==================== Kontrol Paneli ==================== -->
      <div class="card controls">
        <div class="section-title">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
            <circle cx="8.5" cy="8.5" r="1.5"/>
            <polyline points="21 15 16 10 5 21"/>
          </svg>
          Görüntü İçe Aktar
        </div>
        <div class="input-set">
          <div class="file-wrap">
            <input type="file" accept="image/*" id="fileIn" class="file-hidden">
            <button class="file-vis">
              <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                <polyline points="17 8 12 3 7 8"/>
                <line x1="12" y1="3" x2="12" y2="15"/>
              </svg>
              Görüntü Seç
            </button>
          </div>
          <button id="btnPaste" class="btn grey">
            <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
              <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
            </svg>
            Görüntü Yapıştır
          </button>
        </div>
    
        <!-- Ayarlama Parametreleri -->
        <div class="adjustment-section">
          <div class="section-title">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <circle cx="12" cy="12" r="3"/>
              <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
            </svg>
            Temel Ayarlar
          </div>
    
          <div class="range-set">
            <div class="range-head"><span>Renk Sıcaklığı</span><span id="valT">0</span></div>
            <input type="range" id="rangeT" min="-100" max="100" value="0" class="range">
          </div>
    
          <div class="range-set">
            <div class="range-head"><span>Doygunluk</span><span id="valS">100</span></div>
            <input type="range" id="rangeS" min="0" max="200" value="100" class="range">
          </div>
    
          <div class="range-set">
            <div class="range-head"><span>Kontrast</span><span id="valC">100</span></div>
            <input type="range" id="rangeC" min="0" max="200" value="100" class="range">
          </div>
    
          <div class="range-set">
            <div class="range-head"><span>Parlaklık</span><span id="valB">100</span></div>
            <input type="range" id="rangeB" min="0" max="200" value="100" class="range">
          </div>
        </div>
    
        <!-- ====== İçe Aktarılabilir Sanatsal Filtreler ====== -->
        <div class="section-title">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
          </svg>
          Sanatsal Filtreler
        </div>
    
        <!-- Filtre İçe Aktar Butonu -->
        <div class="file-wrap" style="margin-bottom:var(--space-md)">
          <input id="filePreset" type="file" accept=".json" class="file-hidden">
          <button id="btnPreset" class="file-vis">
            <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M12 3v18M3 12h18"/>
            </svg>
            Özel Filtre İçe Aktar
          </button>
        </div>
    
        <!-- Filtre Buton Grubu -->
        <div class="filter-btn-group" id="filterGroup"></div>
    
        <!-- İşlem Butonları -->
        <div class="btn-group">
          <button id="btnAuto" class="btn blue">
            <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
            </svg>
            Otomatik Düzelt
          </button>
          <button id="btnReset" class="btn grey">
            <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M3 2v6h6"/>
              <path d="M3 13a9 9 0 1 0 3-7.7L3 8"/>
            </svg>
            Sıfırla
          </button>
          <button id="btnDL" class="btn green">
            <svg class="btn-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
              <polyline points="7 10 12 15 17 10"/>
              <line x1="12" y1="15" x2="12" y2="3"/>
            </svg>
            Sonucu İndir
          </button>
        </div>
      </div>
    
      <div class="footer">
        ©2025 LINUX DO Görüntü Renk Düzeltme Aracı | <a href="#" target="_blank">Kullanım Kılavuzu</a>
      </div>
    </div>
    
    <!-- ============ JavaScript ============ -->
    <script>
    /* ========= DOM Referansları ========= */
    const fileIn  = document.getElementById('fileIn'),
          btnPaste= document.getElementById('btnPaste'),
          btnAuto = document.getElementById('btnAuto'),
          btnReset= document.getElementById('btnReset'),
          btnDL   = document.getElementById('btnDL'),
          imgOrig = document.getElementById('imgOrig'),
          imgCorr = document.getElementById('imgCorr'),
          cvCorr  = document.getElementById('canvasCorr'),
          ctxCorr = cvCorr.getContext('2d'),
          phOrig  = document.getElementById('phOrig'),
          phCorr  = document.getElementById('phCorr'),
          split   = document.getElementById('splitSlider'),
          compareBox = document.getElementById('compareBox'),
          filterGroup = document.getElementById('filterGroup'),
          filePreset = document.getElementById('filePreset'),
          btnPreset  = document.getElementById('btnPreset'),
          ranges  = {
            T: document.getElementById('rangeT'),
            S: document.getElementById('rangeS'),
            C: document.getElementById('rangeC'),
            B: document.getElementById('rangeB')
          },
          vals    = {
            T: document.getElementById('valT'),
            S: document.getElementById('valS'),
            C: document.getElementById('valC'),
            B: document.getElementById('valB')
          };
    
    let clipPos = 50,           // Kaydırıcı Pozisyonu
        imgURL  = '',           // Orijinal Görüntü URL'si
        baseData = null,        // "Düzeltilmiş" Piksel Önbelleği
        currentFilter = 'none'; // Mevcut Filtre
    
    /* ========= 0. Dahili + Özel Filtre Tablosu ========= */
    const filterDefs = {
      none   : { label:'Hiçbiri', mode:'css',   css:''           },
      cool   : { label:'Soğuk',   mode:'pixel', func:filterCool  },
      vintage: { label:'Vintage', mode:'pixel', func:filterVintage },
      comic  : { label:'Çizgi Roman', mode:'pixel', func:filterComic }
    };
    
    /* ========= 1. Sürgü Değerleri → CSS-Filter String'i ========= */
    function sliderFilterStr(){
      const t = +ranges.T.value,
            s = +ranges.S.value,
            c = +ranges.C.value,
            b = +ranges.B.value;
      const tF = t<0 ? `sepia(${Math.abs(t)/100}) hue-rotate(180deg)`
                     : `sepia(${t/100})`;
      return `${tF} saturate(${s}%) contrast(${c}%) brightness(${b}%)`;
    }
    
    /* ========= 2. Filtre Buton Çubuğunu Oluştur ========= */
    function rebuildFilterBar(){
      filterGroup.innerHTML='';
      Object.entries(filterDefs).forEach(([id,def])=>{
        const btn=document.createElement('button');
        btn.className='btn filter-btn';
        btn.dataset.filter=id;
        btn.textContent=def.label;
        filterGroup.appendChild(btn);
      });
      setActiveBtn();
    }
    rebuildFilterBar();
    
    /* ========= 3. Mevcut Aktif Butonu Ayarla ========= */
    function setActiveBtn(){
      document.querySelectorAll('.filter-btn').forEach(btn=>{
        btn.classList.toggle('active', btn.dataset.filter === currentFilter);
      });
    }
    
    /* ========= 4. Dosya/Yapıştırma ile Görüntü Yükleme ========= */
    fileIn.addEventListener('change',e=>{
      if(e.target.files.length){
        imgURL = URL.createObjectURL(e.target.files[0]);
        loadImage(imgURL);
      }
    });
    btnPaste.addEventListener('click',async ()=>{
      try{
        const items = await navigator.clipboard.read();
        for(const it of items){
          for(const t of it.types){
            if(t.startsWith('image/')){
              const blob = await it.getType(t);
              imgURL = URL.createObjectURL(blob);
              loadImage(imgURL);
              return;
            }
          }
        }
        alert('Panoda görüntü bulunamadı');
      }catch(e){
        alert('Tarayıcı pano API\'sini desteklemiyor');
      }
    });
    
    /* ========= 5. Orijinal Görüntüyü Yükle & Kutu Boyutunu Ayarla ========= */
    function loadImage(url){
      imgOrig.crossOrigin='anonymous';
      imgOrig.onload = ()=>{
        imgOrig.classList.add('loaded');
        phOrig.style.display='none';
        resizeBox();
        reset(false);
      };
      imgOrig.onerror = ()=>{
        alert('Görüntü yüklenemedi');
        imgOrig.classList.remove('loaded');
      };
      imgOrig.src = url;
    }
    window.addEventListener('resize', resizeBox);
    function resizeBox(){
      if(!imgOrig.naturalWidth) return;
      const r = imgOrig.naturalHeight / imgOrig.naturalWidth;
      compareBox.style.height =
        Math.min(window.innerHeight * .8,
                 compareBox.offsetWidth * r) + 'px';
    }
    
    /* ========= 6. Kaydırıcı Sürükleme ========= */
    split.addEventListener('mousedown', startDrag);
    split.addEventListener('touchstart', startDrag, {passive:true});
    function startDrag(e){
      e.preventDefault();
      document.addEventListener('mousemove', moveDrag);
      document.addEventListener('mouseup', stopDrag);
      document.addEventListener('touchmove', moveDrag, {passive:true});
      document.addEventListener('touchend', stopDrag);
      document.addEventListener('touchcancel', stopDrag);
    }
    function moveDrag(e){
      const rect = compareBox.getBoundingClientRect();
      const x = (e.touches ? e.touches[0].clientX : e.clientX) - rect.left;
      clipPos = Math.max(0, Math.min(100, (x/rect.width)*100));
      updateClip();
    }
    function stopDrag(){
      document.removeEventListener('mousemove', moveDrag);
      document.removeEventListener('mouseup', stopDrag);
      document.removeEventListener('touchmove', moveDrag);
      document.removeEventListener('touchend', stopDrag);
      document.removeEventListener('touchcancel', stopDrag);
    }
    function updateClip(){
      split.style.left = clipPos + '%';
      document.querySelectorAll('.corr').forEach(el=>{
        el.style.clipPath = `inset(0 0 0 ${clipPos}%)`;
      });
    }
    
    /* ========= 7. Otomatik LAB Düzeltme ========= */
    btnAuto.addEventListener('click', ()=>{
      if(!imgOrig.naturalWidth){ alert('Lütfen önce bir görüntü yükleyin'); return; }
    
      /* 1. 800px'i geçmeyecek şekilde ölçeklendir */
      const maxSide = 800;
      const scale = Math.min(1, maxSide / Math.max(imgOrig.naturalWidth,
                                                  imgOrig.naturalHeight));
      cvCorr.width  = Math.round(imgOrig.naturalWidth * scale);
      cvCorr.height = Math.round(imgOrig.naturalHeight * scale);
      ctxCorr.drawImage(imgOrig, 0, 0, cvCorr.width, cvCorr.height);
    
      /* 2. Basit gray-world + LAB a/b nötralizasyonu */
      const imgData = ctxCorr.getImageData(0,0,cvCorr.width,cvCorr.height),
            d = imgData.data, len = d.length/4;
      let aSum=0, bSum=0;
      for(let i=0;i<d.length;i+=4){
        const [,a,b] = rgb2lab(d[i], d[i+1], d[i+2]);
        aSum += a; bSum += b;
      }
      const aAvg = aSum/len, bAvg = bSum/len, k = 1;
      for(let i=0;i<d.length;i+=4){
        let [L,a,b] = rgb2lab(d[i], d[i+1], d[i+2]);
        a -= k * aAvg; b -= k * bAvg;
        const [r,g,bl] = lab2rgb(L,a,b);
        d[i]=r; d[i+1]=g; d[i+2]=bl;
      }
      ctxCorr.putImageData(imgData,0,0);
    
      /* 3. Temel piksel verisini kaydet, filtreleri sıfırla */
      baseData = ctxCorr.getImageData(0,0,cvCorr.width,cvCorr.height);
      currentFilter = 'none';
      setActiveBtn();
    
      /* 4. Sonucu göster */
      imgCorr.src = cvCorr.toDataURL('image/png');
      imgCorr.style.display='block';
      imgCorr.classList.add('loaded');
      cvCorr.style.display='none';
      phCorr.style.display='none';
      updateClip();
      
      // Başarı animasyonu ekle
      btnAuto.classList.add('success');
      setTimeout(() => btnAuto.classList.remove('success'), 1000);
    });
    
    /* ========= 8. Dört Sürgü ========= */
    Object.entries(ranges).forEach(([k,el])=>{
      el.addEventListener('input',()=>{
        vals[k].textContent = el.value;
        vals[k].style.opacity = 1;
        setTimeout(() => {
          vals[k].style.opacity = 0.8;
        }, 200);
        applyFilter();   // CSS güncelle
      });
    });
    
    /* ========= 9. Filtre Buton Olayları ========= */
    filterGroup.addEventListener('click', e=>{
      const btn = e.target.closest('.filter-btn');
      if(!btn) return;
      currentFilter = btn.dataset.filter;
      setActiveBtn();
      applyNamedFilter();
    });
    
    /* ========= 10. CSS Sürgülerini Uygula ========= */
    function applyFilter(){
      const def = filterDefs[currentFilter] || filterDefs.none;
      const finalCss = (def.mode==='css'?def.css+' ':'') + sliderFilterStr();
      imgCorr.style.filter = cvCorr.style.filter = finalCss;
    }
    
    /* ========= 11. Belirtilen Filtreyi Uygula ========= */
    function applyNamedFilter(){
      if(!baseData){
        alert('Lütfen önce "Otomatik Düzelt" işlemini yapın');
        return;
      }
      const def = filterDefs[currentFilter] || filterDefs.none;
    
      /* ---- pixel tipi ---- */
      if(def.mode==='pixel' && typeof def.func === 'function'){
        let imgData = new ImageData(
          new Uint8ClampedArray(baseData.data),
          baseData.width, baseData.height);
    
        def.func(imgData, imgData.data, imgData.width, imgData.height);
    
        ctxCorr.putImageData(imgData, 0, 0);
        imgCorr.src = cvCorr.toDataURL('image/png');
        imgCorr.style.display='block';
        phCorr.style.display='none';
      }
    
      /* ---- css tipi ---- */
      if(def.mode==='css'){
        ctxCorr.putImageData(baseData,0,0);
        imgCorr.src = cvCorr.toDataURL('image/png');
      }
    
      applyFilter();
      updateClip();
    }
    
    /* ========= 12. Filtre JSON İçe Aktarma ========= */
    btnPreset.addEventListener('click',()=>filePreset.click());
    filePreset.addEventListener('change',e=>{
      if(!e.target.files.length) return;
      const fr=new FileReader();
      fr.onload=()=>{
        try{
          const json=JSON.parse(fr.result);
          loadPreset(json);
          rebuildFilterBar();
          // Başarı bildirimi ekle
          const toast = document.createElement('div');
          toast.className = 'toast';
          toast.textContent = 'Filtre başarıyla içe aktarıldı';
          document.body.appendChild(toast);
          setTimeout(() => {
            toast.style.opacity = 0;
            setTimeout(() => toast.remove(), 500);
          }, 2000);
        }catch(err){
          alert('JSON ayrıştırma hatası: '+err.message);
        }
      };
      fr.readAsText(e.target.files[0],'utf-8');
    });
    
    function loadPreset(list){
      (Array.isArray(list)?list:[list]).forEach(f=>{
        if(!f.id) return;
        if(f.mode==='css' && f.css){
          filterDefs[f.id] = {label:f.label||f.id,mode:'css',css:f.css};
        }else if(f.mode==='pixel'){
          let fn=null;
          if(f.funcName && typeof window[f.funcName]==='function'){
            fn = window[f.funcName];
          }else if(f.script){
            fn = new Function('imgData','data','width','height',f.script);
          }
          if(fn){
            filterDefs[f.id]={label:f.label||f.id,mode:'pixel',func:fn};
          }
        }
      });
    }
    
    /* ========= 13. İndirme ========= */
    btnDL.addEventListener('click', ()=>{
      if(imgCorr.src){
        const a=document.createElement('a');
        a.href=imgCorr.src;
        a.download='filtrelenmis_goruntu.png';
        a.click();
        
        // İndirme animasyonu ekle
        btnDL.classList.add('active');
        setTimeout(() => btnDL.classList.remove('active'), 1000);
      }else alert('İndirilecek görüntü yok');
    });
    
    /* ========= 14. Sıfırlama ========= */
    btnReset.addEventListener('click', ()=>reset(false));
    function reset(keepCorr){
      ranges.T.value=0;
      ranges.S.value=ranges.C.value=ranges.B.value=100;
      vals.T.textContent=0;
      vals.S.textContent=vals.C.textContent=vals.B.textContent=100;
    
      currentFilter='none';
      setActiveBtn();
      applyFilter();
    
      if(!keepCorr){
        imgCorr.style.display='none';
        imgCorr.classList.remove('loaded');
        cvCorr.style.display='none';
        phCorr.style.display='flex';
        imgCorr.src='';
        baseData=null;
      }
      clipPos=50;
      updateClip();
    }
    
    /* ========= 15. Piksel Filtre Algoritmaları ========= */
    function clamp(v){return v<0?0:(v>255?255:v);}
    
    /* ----- Soğuk ----- */
    function filterCool(imgData){
      const d=imgData.data;
      for(let i=0;i<d.length;i+=4){
        let r=d[i]*1.1, g=d[i+1], b=d[i+2]*1.2;
        const lum=r+g+b;
        if(lum<200) b+=10;
        d[i]=clamp(r); d[i+1]=clamp(g); d[i+2]=clamp(b);
      }
      return imgData;
    }
    /* ----- Vintage ----- */
    function filterVintage(imgData){
      const d=imgData.data, w=imgData.width, h=imgData.height;
      const cx=w/2, cy=h/2, maxD=Math.hypot(cx,cy);
      for(let y=0;y<h;y++){
        for(let x=0;x<w;x++){
          const idx=(y*w+x)*4;
          const r=d[idx], g=d[idx+1], b=d[idx+2];
    
          let tr=0.393*r+0.769*g+0.189*b;
          let tg=0.349*r+0.686*g+0.168*b;
          let tb=0.272*r+0.534*g+0.131*b;
    
          tr*=0.8; tg*=0.8; tb*=0.8;
    
          const v=1-0.5*Math.hypot(x-cx,y-cy)/maxD;
          tr*=v; tg*=v; tb*=v;
    
          const n=(Math.random()-.5)*20;
          d[idx]=clamp(tr+n); d[idx+1]=clamp(tg+n); d[idx+2]=clamp(tb+n);
        }
      }
      return imgData;
    }
    /* ----- Çizgi Roman ----- */
    function filterComic(imgData){
      const w=imgData.width,h=imgData.height,src=imgData.data;
      const gray=new Uint8Array(w*h),edge=new Uint8Array(w*h);
    
      for(let i=0,j=0;i<src.length;i+=4,j++){
        gray[j]=0.299*src[i]+0.587*src[i+1]+0.114*src[i+2];
      }
      for(let y=1;y<h-1;y++){
        for(let x=1;x<w-1;x++){
          const i=y*w+x;
          const gx=-gray[i-w-1]-2*gray[i-1]-gray[i+w-1]+gray[i-w+1]+2*gray[i+1]+gray[i+w+1];
          const gy=-gray[i-w-1]-2*gray[i-w]-gray[i-w+1]+gray[i+w-1]+2*gray[i+w]+gray[i+w+1];
          edge[i]=(Math.abs(gx)+Math.abs(gy))>250?255:0;
        }
      }
      const lvl=v=>[0,85,170,255][Math.floor(v/64)];
      for(let i=0,j=0;i<src.length;i+=4,j++){
        if(edge[j]){src[i]=src[i+1]=src[i+2]=0;}
        else{
          src[i]=lvl(src[i]); src[i+1]=lvl(src[i+1]); src[i+2]=lvl(src[i+2]);
        }
      }
      return imgData;
    }
    
    /* ========= 16. Renk Uzayı Araçları ========= */
    const W = {xn:0.95047,yn:1,zn:1.08883};
    const srgb2lin = x=> (x/=255)<=0.04045?x/12.92:Math.pow((x+0.055)/1.055,2.4);
    const lin2srgb = x=>{
      x=Math.max(0,Math.min(1,x));
      return Math.round((x<=0.0031308?12.92*x:1.055*Math.pow(x,1/2.4)-0.055)*255);
    };
    function rgb2xyz(r,g,b){
      r=srgb2lin(r);g=srgb2lin(g);b=srgb2lin(b);
      return [0.4124*r+0.3576*g+0.1805*b,
              0.2126*r+0.7152*g+0.0722*b,
              0.0193*r+0.1192*g+0.9505*b];
    }
    function xyz2rgb(x,y,z){
      const r=3.2406*x-1.5372*y-0.4986*z,
            g=-0.9689*x+1.8758*y+0.0415*z,
            b=0.0557*x-0.2040*y+1.0570*z;
      return [lin2srgb(r),lin2srgb(g),lin2srgb(b)];
    }
    function xyz2lab(x,y,z){
      const f=t=>(t>0.008856)?Math.cbrt(t):(7.787*t+16/116);
      const fx=f(x/W.xn), fy=f(y/W.yn), fz=f(z/W.zn);
      return [116*fy-16,500*(fx-fy),200*(fy-fz)];
    }
    function lab2xyz(L,a,b){
      const fy=(L+16)/116,fx=a/500+fy,fz=fy-b/200;
      const f=t=>{const t3=t*t*t;return (t3>0.008856)?t3:(t-16/116)/7.787};
      return [W.xn*f(fx), W.yn*f(fy), W.zn*f(fz)];
    }
    function rgb2lab(r,g,b){return xyz2lab(...rgb2xyz(r,g,b))}
    function lab2rgb(L,a,b){return xyz2rgb(...lab2xyz(L,a,b))}
    
    /* ========= 17. Toast Bildirim Stillerini Ekle ========= */
    const toastStyle = document.createElement('style');
    toastStyle.textContent = `
    .toast {
      position: fixed;
      bottom: 20px;
      left: 50%;
      transform: translateX(-50%);
      background: rgba(0,0,0,0.8);
      color: white;
      padding: 10px 20px;
      border-radius: 4px;
      font-size: 14px;
      z-index: 1000;
      opacity: 1;
      transition: opacity 0.5s;
      box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    }
    
    .btn.active, .btn.success {
      transform: scale(1.05);
      transition: transform 0.2s;
    }
    
    @keyframes pulse {
      0% { transform: scale(1); }
      50% { transform: scale(1.05); }
      100% { transform: scale(1); }
    }
    `;
    document.head.appendChild(toastStyle);
    
    /* ========= Başlangıç İşlemleri ========= */
    updateClip();
    applyFilter();
    
    // Sağ tık menüsünü devre dışı bırak, kullanıcı deneyimini artır
    document.addEventListener('contextmenu', e => e.preventDefault());
    
    // Görüntüler yüklendiğinde sınıf ekle
    imgOrig.addEventListener('load', () => {
      imgOrig.classList.add('loaded');
    });
    imgCorr.addEventListener('load', () => {
      imgCorr.classList.add('loaded');
    });
    </script>
    </body>
    </html>
  • 27-04-2025, 13:21:48
    #2
    snapchat filtre apileri ücretsiz onlarıda DAHİL EDEBİLRİSİN.
  • 27-04-2025, 13:23:36
    #3
    Üyeliği durduruldu
    shms adlı üyeden alıntı: mesajı görüntüle
    snapchat filtre apileri ücretsiz onlarıda DAHİL EDEBİLRİSİN.
    altta json yeri var tek tek ekleyemem siz oradan ekleyip deneyin.
    Örnek Json
    [
        {
            "id"   : "warm",
            "label": "Sıcak Ton",
            "mode" : "css",
            "css"  : "sepia(25%) brightness(105%) saturate(120%)"
        },
        {
            "id"   : "noir",
            "label": "Siyah Beyaz Çizgi Roman",
            "mode" : "pixel",
            "script": "for(let i=0;i<data.length;i+=4){const g=0.299*data[i]+0.587*data[i+1]+0.114*data[i+2];data[i]=data[i+1]=data[i+2]=g>128?255:0;}"
        }
    ]