JavaScript ile Görselleri Yüklemeden Önizleme Yapmak

Bir çok yerde denk gelmişsinizdir, bir fotoğraf yüklerken seçtiğiniz anda sayfada önizlemesi gelir. Boyutu her ne olursa olsun, hiç beklemeden bu işlem gerçekleşir. Bunu anlık olarak javascript ile nasıl yapabileceğimi merak ettikten sonra biraz araştırma yaptım ve bulduklarımı test ederek başarıya ulaştım.. Şimdi sizlere de bunu göstermek istiyorum.

İlk olarak buna benzer örnekleri şu sitelerde görebilirsiniz;
– 500px.com
– twitter.com
– plus.google.com

Nasıl Yapılır?

Bunu bir API sayesinde (FileReader) yapıyoruz. Ancak bu javascript api’si her tarayıcıda desteklenmiyor. IE için 10 ve üstü destekliyor örneğin ???? Tahmin etmişsinizdir zaten. Her neyse, ie’den girenleri tespt edip ona göre farklı şeyler yaptırabilirsiniz, bu size kalmış. İşte şuan için tarayıcı desteği şu şekildedir;

İlk olarak yapmamız gereken şey, input change olduğunda bunu yakalamak..

$('input').change(function(e){
   // kodlar..
});

Şimdi ise seçilen fotoğraf objesini tanımlayalım;

var fotograf = e.target.files[0];

evet, objemizde elimizde.. Şimdi FileReader apisini başlatalım.

var reader = new FileReader();

Şimdi ise resmi okuyalım. Bunun için readAsDataURL metodunu kullanacağız. Parametre olarak fotoğraf objesini vereceğiz.

reader.readAsDataURL(fotograf);

Son olarak okuma işlemi başarılı ise onload ile gelen değeri alıp görünmesini istediğimiz bir yere yazdırağız.

reader.onload = function(evt){
	$('#result').attr('src', evt.target.result);
}

İşte hepsi bu kadar ????

Daha fazlası için;
https://developer.mozilla.org/en-US/docs/Web/API/FileReader

Tarayıcıların API desteğini bulmak

Kullanıcının girdiği tarayıcı api’yi desteklemiyor olabilir. Bu durumda bunu tespit etmek ve ona göre işlem yazmak gerekir.. API tespiti için şöyle bir mantık yürütebiliriz.

if (window.File && window.FileReader && window.FileList && window.Blob) {
     // destekliyor
} else {
     // desteklemiyor!
}

Fotoğraf Özelliklerini Bulmak (Php, Js)

Yakın zamanda yeni bir fotoğraf makinesi aldım ve amatör olarak fotoğraf çekmeye başladım.. Bundan dolayıda hemen bir 500px.com üyeliği aldım ve fotoğraflarımı yüklerken orada bir şey dikkatimi çekti, hatta dikkat çekmekle birlikte çok hoşuma gitti ???? Yüklediğim fotoğrafa ait bilgileri görebiliyordum, hangi marka ve model fotoğraf makinası ile çektiğimi, zoom değerini vs. vs..

Daha sonra bunu php ile nasıl yapabileceğimi biraz araştırdıktan sonra bir şeyler buldum, test ettim ve güzel bir şekilde çalıştığını gördüm. Bunu sizlerle de paylaşmak istiyorum..

Not: Beni 500px üzerinden takip etmek isterseniz, adresim aşağıdadır ????
http://500px.com/TayfunErbilen

Bir şeyi arıyorsanız bir anahtar kelimeniz olmalı..
Bizim anahtar kelimemiz belli; “Exif

Bu anahtar kelime ile diğer diller içinde bunu bulabiliriz..
Bkz: javascript Exif

Php’de bu işi yapan exif_read_data() adında bir fonksiyon.
http://www.php.net/manual/en/function.exif-read-data.php

En basit haliyle yapmanız gereken tek şey, resmin yolunu belirtmeniz.

<?php
$exif = exif_read_data('tayfunerbilen.png');
print_r( $exif );
?>

Ve çıktısı en basit haliyle şöyle olacaktır;

Array
(
    [FileName] => IMG_5236.JPG
    [FileDateTime] => 1378615652
    [FileSize] => 3438950
    [FileType] => 2
    [MimeType] => image/jpeg
    [SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, INTEROP, MAKERNOTE
    [COMPUTED] => Array
        (
  ........

Şimdi bizim için önemli olan fotoğraf bilgilerini alıp değişkenlere aktaralım ve ekrana yazdıralım ????

<?php

	$exif = exif_read_data('IMG_5236.JPG');

	$kamera = $exif['Make'];
	$kameraModel = $exif['Model'];
	$fDuragi = $exif['COMPUTED']['ApertureFNumber'];
	$isoHizi = $exif['ISOSpeedRatings'];
	$pozlandirma = $exif['ExposureProgram'];
	$odakUzunluk = $exif['FocalLength'];
	$deklansorHiz = $exif['ExposureTime'];
	$cekilmeZamani = $exif['DateTime'];

>

Ve yazdıralım;

<strong>Kamera:</strong> <?php echo $kamera; ?><hr />
<strong>Kamera Modeli:</strong> <?php echo $kameraModel; ?><hr />
<strong>F Durağı:</strong> <?php echo $fDuragi; ?><hr />
<strong>ISO Hızı:</strong> <?php echo $isoHizi; ?><hr />
<strong>Pozlandırma:</strong> <?php echo $pozlandirma; ?><hr />
<strong>Odak Uzunluğu:</strong> <?php echo $odakUzunluk; ?> mm<hr />
<strong>Deklanşör Hızı:</strong> <?php echo $deklansorHiz; ?> mm<hr />
<strong>Çekilme Zamanı:</strong> <?php echo $cekilmeZamani; ?><hr />

Ancak her fotoğrafda olmayacağını unutmayın. Bu yüzden isset() ve empty() kullanarak kontrollü bir şekilde ekrana yazdırmayı unutmayın.

javascript ile Fotoğraf Bilgilerini Almak

Bunun için google’a “javascript exif” diye aratmanız yeterli. Bir çok eklenti mevcut, ben bir tanesini kullanarak kolayca işlem yapabildim.. Kullandığım eklenti;

https://github.com/jseidelin/exif-js

Kullanımı;

Önce jquery kütüphanesini ve eklentinin 2 js dosyasını sayfaya dahil ediyoruz. Daha sonra input change olduğunda bu olayı yakalayıp fotoğrafın yolunu eklentiye gönderiyor ve değerleri alarak istediğimiz herhangi bir yere yazdırıyoruz..

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="binaryajax.js"></script>
<script type="text/javascript" src="exif.js"></script>
<meta charset="utf8" />
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
font-family: Arial;
font-size: 12px
}
body {
padding: 15px;
background: #f5f5f5
}
.container {
width: 400px;
margin: 25px auto
}
.fotograf {
border: 1px solid #ddd;
padding: 15px;
background: #fff;
display: block;
margin-bottom: 10px
}
#ozellikler {
border: 1px solid #ddd;
border-bottom: none;
margin-top: 10px;
display: none
}
#ozellikler li {
padding: 7px;
background: #fff;
border-bottom: 1px solid #ddd
}
#ozellikler li:nth-child(even) {
background: #eee
}
</style>
</head>
<body>
<div class="container">
<label class="fotograf">
<strong>Fotoğraf Seçin:</strong> 
<input type="file" accept="image/jpg" id="fotograf">
</label>
<div id="result">
<ul id="ozellikler"></ul>
</div>
</div>
<script type="text/javascript">
if (window.File && window.FileReader && window.FileList && window.Blob) {
$('#fotograf').change(function(e){
var fotograf = e.target.files[0];
var ozellikler = $('ul#ozellikler');
EXIF.getData(fotograf, function(){
ozellikler.fadeIn().html('');
var kamera = EXIF.getTag(this, 'Make');
if ( kamera ) ozellikler.append('<li><strong>Kamera:</strong> ' + kamera + '</li>');
var model = EXIF.getTag(this, 'Model');
if ( model ) ozellikler.append('<li><strong>Model:</strong> ' + model + '</li>');
var fDuragi = EXIF.getTag(this, 'FNumber');
if ( fDuragi ) ozellikler.append('<li><strong>F Durağı:</strong> ' + fDuragi + '</li>');
var isoHizi = EXIF.getTag(this, 'ISOSpeedRatings');
if ( isoHizi ) ozellikler.append('<li><strong>ISO Hızı:</strong> ' + isoHizi + '</li>');
var pozlandirma = EXIF.getTag(this, 'ExposureBias');
if ( pozlandirma ) ozellikler.append('<li><strong>Pozlandırma:</strong> ' + pozlandirma + '</li>');
var odakUzunluk = EXIF.getTag(this, 'FocalLength');
if ( odakUzunluk ) ozellikler.append('<li><strong>Odak Uzunluğu:</strong> ' + odakUzunluk + '</li>');
var deklansorHiz = EXIF.getTag(this, 'ExposureTime');
if ( deklansorHiz ) ozellikler.append('<li><strong>Daklanşör Hızı:</strong> ' + deklansorHiz + '</li>');
var cekilmeZamani = EXIF.getTag(this, 'DateTime');
if ( cekilmeZamani ) ozellikler.append('<li><strong>Çekilme Zamanı:</strong> ' + cekilmeZamani + '</li>');
});
});
}
</script>
</body>
</html>

PHPMailer Sınıfı ile Gmail Üzerinden E-Posta Gönderimi

Öncelikle bu sınıfı yazana bir teşekkür edelim ???? Daha sonra ise ilk olarak sınıfı indireceğiniz adresi vereyim;

https://code.google.com/a/apache-extras.org/p/phpmailer/

Burada tahmin edebileceğiniz gibi “downloads” sekmesinden en çok indirileni indiriyoruz.Not: Eğer indirme adresinde ssl’den dolayı hata alırsanız “yine de devam et” diyerek indirme işlemine devam edin.

Okumaya devam et “PHPMailer Sınıfı ile Gmail Üzerinden E-Posta Gönderimi”

Ternary (Üçlü) Operatör Kullanımı (PHP)


Bu operatör çok basit şekilde çalışır.. Ve yapısı şöyledir;

KOŞUL ? DOĞRUYSA : YANLIŞSA

Bunu php’de şöyle bir örnek ile daha iyi anlayabiliriz;

$sayfa = isset($_GET['sayfa']) ? $_GET['sayfa'] : 1;

Burada eğer sayfa adında bir get parametresi var ise onun değerini yok ise 1 değerini $sayfa değişkenine atamış olduk.. Bunu uzun olarak if koşulu ile şöyle yapabilirdik;

if ( isset($_GET['sayfa']) ){
    $sayfa = $_GET['sayfa'];
} else {
    $sayfa = 1;
}

Ancak gördüğünüz gibi ternary operatör işimizi çok daha kolaylaştırıyor ve işlemi tek satır haline indiriyor.. Ayrıca iç içede kullanımı vardır.. Örnek vermek gerekirse;

$deger = 1;
$sonuc = ($deger === 1 ? 'Doğru' : ($deger === 2 ? '1 Yanlış' : ($deger === 3 ? 'Hatalı' : 'Tamamen Hatalı')));

Ancak genelde bu şekilde iç içe kullanımı çok okunaklı olmadığı için tavsiye etmem. Tek satırlı işlemler için ideal bir operatördür ve bilmenizde fayda var.

“X Zaman Önce” Yazıldı Fonksiyonu

Bir çok paylaşım sitesinde gördüğümüz “x zaman önce” yazıldı tarzında tarihlerin ne zaman yazıldığını gösteren bir fonksiyondur.

function timeConvert ( $zaman ){
	$zaman =  strtotime($zaman);
	$zaman_farki = time() - $zaman;
	$saniye = $zaman_farki;
	$dakika = round($zaman_farki/60);
	$saat = round($zaman_farki/3600);
	$gun = round($zaman_farki/86400);
	$hafta = round($zaman_farki/604800);
	$ay = round($zaman_farki/2419200);
	$yil = round($zaman_farki/29030400);
	if( $saniye < 60 ){
		if ($saniye == 0){
			return "az önce";
		} else {
			return $saniye .' saniye önce';
		}
	} else if ( $dakika < 60 ){
		return $dakika .' dakika önce';
	} else if ( $saat < 24 ){
		return $saat.' saat önce';
	} else if ( $gun < 7 ){
		return $gun .' gün önce';
	} else if ( $hafta < 4 ){
		return $hafta.' hafta önce';
	} else if ( $ay < 12 ){
		return $ay .' ay önce';
	} else {
		return $yil.' yıl önce';
	}
}

Kullanımı;

<?php
// .. timeConvert fonksiyonu
$tarih = "2013-09-22 15:25:33";
echo timeConvert($tarih);
?>

Dizide Tekrarlanan Elemanları Silme “array_unique()” (PHP)

Bir diziniz var ancak bu dizide birden fazla aynı elemandan bulunuyor ve bu sizi rahatsız ediyor.. Bir şekilde aynı olan dizi elemanlarını kaldırıp sadece bir tanesinin kalmasını istiyorsunuz.. İşte bu durumda php bize şöyle bir fonksiyon sunuyor;
http://php.net/manual/en/function.array-unique.php

Örnek kullanımı;

<?php

$array = array(
	"tayfun",
	"erbilen",
	"tayfun",
	"erbilen.net",
	"tayfun"
);
$newArray = array_unique($array);

print_r( $newArray );

/*

Array
(
    [0] => tayfun
    [1] => erbilen
    [3] => erbilen.net
)

*/

?>

jQuery UI Datepicker için Gün Filtresi

Geçenlerde sevgili Mert abim, bu konu hakkında benden ufak bir ricada bulundu. Biraz araştırdıktan sonra mantığı kavradım ve kullanmak için basit bir fonksiyon hazırladım. Bu fonksiyon ile datepicker için gün filtresi yapabiliyorusunuz..

Bize lazım olan sadece mevcut zamandan şu kadar gün sonrasını seçememe gibi bir olaydı.. Bende ona göre bir fonksiyon yazdım, ancak fonksiyonu biraz incelerseniz istediğiniz kısımları kendinizde devam ettirebilirsiniz diye düşünüyorum..

Öncelikle fonksiyon kodlarını vereyim;

function gunFiltre(date, dlimit, goncesi, pgun, agun) {
	
	/**
	 * Mevcut günden sonra kaç gün daha gözükebilsin?
	 */
	var gunLimit = dlimit ? dlimit : 0;
	
	/**
	 * Mevcut günden önceki diğer günlerin hepsi gözüksün
	 */
	var gunOncesi = goncesi;
	
	/**
	 * Günleri belirleyip işlem yaptırmak isterseniz bu diziye pasif olmasını istediğiniz günleri yazın
	 */
	var pasifGun = pgun ? pgun : [];
	
	/**
	 * Günleri belirleyip işlem yaptırmak isterseniz bu diziye aktif olmasını istediğiniz günleri yazın
	 */
	var aktifGun = agun ? agun : [];
	
	var bugunTarih = String(new Date()).split(' ');
	var mevcutTarih = String(date).split(' ');
	var ayDogrumu = bugunTarih[1] == mevcutTarih[1];
	
	/** 
	 * belirli günleri pasif eder
	 */
	if ( pasifGun.length > 0 ){
		if ( ayDogrumu && pasifGun.indexOf(parseInt(mevcutTarih[2])) != -1) {
			return [false];
		} else {
			return [true];
		}
	}
	
	/** 
	 * belirli günleri aktif eder
	 */
	if ( aktifGun.length > 0 ){
		if ( ayDogrumu && aktifGun.indexOf(parseInt(mevcutTarih[2])) != -1) {
			return [true];
		} else {
			return [false];
		}
	}
	
	/**
	 * gün limiti belirlenmişse mevcut zamandan o gün limiti kadarından sonrasını pasif yapar
	 */
	if ( gunLimit !== 0 && ayDogrumu ){
		for ( i = 0; i <= gunLimit; i++ ){
			if ( (parseFloat(bugunTarih[2]) + i) == mevcutTarih[2] ){
				return [true];
			}
		}
	}
	
	/**
	 * mevcut zamandan önceki günleri eğer belirlenmiş ise pasif yapar
	 */
	if ( gunOncesi === true && ayDogrumu ){
		if ( mevcutTarih[2] < parseFloat(bugunTarih[2]) ) {
			return [true];
		}
	}
	
	if ( ayDogrumu && gunLimit !== 0 ){
		return [false];
	} else {
		return [true];
	}
	
}

Nasıl kullanacağız?

Örnek kullanımları şöyle;

Sadece bugün ve 3 gün sonrası aktif olsun, diğer günler pasif olsun.

$('#datepicker').datepicker({
	beforeShowDay: function(tarih){
		return gunFiltre(tarih, 3);
	}
});

Bugünden önceki günler ve bugünden sonraki 3 gün hariç diğer günler pasif olsun.

$('#datepicker').datepicker({
	beforeShowDay: function(tarih){
		return gunFiltre(tarih, 3, true);
	}
});

Ayın sadece 1,7 ve 8. günleri pasif olsun;

$('#datepicker').datepicker({
	beforeShowDay: function(tarih){
		return gunFiltre(tarih, 0, true, [1, 7, 8]);
	}
});

Ayın sadece 1,5 ve 12. günleri aktif olsun;

$('#datepicker').datepicker({
	beforeShowDay: function(tarih){
		return gunFiltre(tarih, 0, true, [], [1,5,12]);
	}
});

IE7 Float Sorunu ve Çözümü

Bu sorunla bir çok kez karşılaştım.. Sorun nesneye verdiğimiz float’tan kaynaklı olarak kaymaya yol açıyor. Önce bir örnek göstereyim..

Html kodlarımız;

<div class="test">
	Tayfun Erbilen: <img src="resim.jpg" alt="" height="60" />
</div>

CSS kodlarımız;

.test {
	width: 200px;
	border: 1px solid #ddd;
	overflow: hidden;
	padding: 10px
}
.test img {
	float: right
}

Sonuç;

Çözüm

Çözüm basit. Float uyguladığımız nesneyi başa alacağız.. Yani yazıdan öncesine ekleyeceğiz. Yani;

<div class="test">
	<img src="resim.jpg" alt="" height="60" /> Tayfun Erbilen:
</div>

Ve sonuç;

Evet bir sorunun daha üstesinden gelmiş olduk ???? IE ile bol dertli günler.

jQuery ZeroClipboard ile Yazı Kopyalama İşlemi

Bildiğiniz gibi ctrl + c yaparak yazıları kopyalama işlemi yapabiliyoruz.. Ancak bunu herhangi bir butona tıklandığında yapabilsek güzel olmaz mıydı? Evet, bu işlemi yapabilmek için ZeroClipboard eklentisini kullanarak çok kolay bir şekilde bu işlemi kusursuz hale getirebiliriz.. O halde başlamadan önce eklenti yazarı SteamDev‘e teşekkürlerimizi sunalım ???? Ve hadi başlayalım..

Adım 1

İlk olarak http://steamdev.com/zclip/ adresine gidelim ve Download altındaki sıkıştırılmış js dosyası ve swf dosyalarını bilgisayarımıza indirelim..

http://steamdev.com/zclip/js/jquery.zclip.min.jshttp://zeroclipboard.googlecode.com/svn-history/r10/trunk/ZeroClipboard.swf

Adım 2

Şimdide jquery kütüphanemizi indirelim.
http://jquery.com/download/

Adım 3

İndirdiklerimizi bir klasör altında toplayalım.. Ve ek olarak index.html ve style.css dosyalarını oluşturalım.

Adım 4

index.html dosyasını açalım ve standart html etiketlerini yazalım. Daha sonra gerekli dosyalarımızı dahil edelim.. Yani kısaca şu kodlarımızı yazalım;

<!DOCTYPE HTML>
<html lang="tr">
<head>
	<meta charset="UTF-8">
	<script type="text/javascript" src="jquery.js"></script>
	<script type="text/javascript" src="jquery.zclip.min.js"></script>
	<link rel="stylesheet" href="style.css" />
</head>
<body>

</body>
</html>

Adım 5

Gerekli html kodlarımız ise şu şekilde;

<input type="text" class="input1" value="test et!" />
<button class="kopyala" data-content=".input1">Kopyala</button>

Burada data-content değeri olarak hangi nesneyi belirtirseniz onun içeriğini alır. (Bir form nesnesi olduğu sürece.)

Adım 6

Şimdi geldi jquery kısmına.. Çok basit bir kullanımı var;

$(function(){

	$('button.kopyala').each(function(){
		var content = $(this).data('content');
		$(this).zclip({
			path: 'ZeroClipboard.swf',
			copy: $(content).val()
		});
	});
	
});

Gördüğünüz gibi tüm button.kopyala nesnelerini bir döngüye soktuk ve tek tek content değerlerini alıp zclip() eklentisini uyguladık. Aslında tıklama işlemi ilede bunu yapabilirdik ancak ilk etapta görmeyeceği için sorun olurdu.. Her neyse, şimdi test etmek için butona basalım ve sonucu görelim..

Evet, şimdi şöyle bir sıkıntımız var.. Örneğin input’un içeriğine yeni bir şeyler yazıp kopyala dediğimizde yine eskisi neyse onu kopyalıyor.. Bu yüzden eğer böyle bir durumda güncel olanı almak isterseniz input’a bir keyup() uygulayabilirsiniz. Yani jquery kodlarımızı şöyle değiştireceğiz;

$(function(){

	$('button.kopyala').each(function(){
		var elem = $(this),
			content = elem.data('content');
		elem.zclip({
			path: 'ZeroClipboard.swf',
			copy: $(content).val()
		});
		$(content).keyup(function(){
			elem.zclip({
				path: 'ZeroClipboard.swf',
				copy: $(content).val()
			});
		});
	});
	
});

Ama tabi bunu pek tavsiye etmem orası ayrı ???? Bir çok kez ekliyor çünkü zclip’i. Dolayısı ile sabit metinleri kopyalatmak için ideal kullanım ilk örnekteki gibi olanıdır.

İndir

http://yadi.sk/d/197f74Cg7ZDzK

CSS ile Yazı Seçimini Engellemek (user-select)

Eğer touch ekranlar için CSS kodlaması yapıyorsanız, böyle bir sorunla karşılaşabilirsiniz.. Özellikle makinalar dandik ve kullanan kişilerde bu işi bilmeyenlerden ise gereksiz tıklamalar ile nesne içerisindeki değerleri seçeceklerdir.. Bunun olmasını önlemek için CSS imdadımıza yetişiyor.. Tüm modern tarayıcılarda ve IE10 olmak üzere ön ekler ile birlikte kullanıldığında herhangi bir sorunla karşılaşmıyorsunuz.. Bu işlem için user-select değerini none yapmamız yeterli.

Tüm elemanlara uygulamak için gerekli CSS kodu;

*:not(input):not(textarea) {
	-moz-user-select: -moz-none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-o-user-select: none;
	-ms-user-select: none;
	user-select: none
}

Ya da bazı belli başlı elemanlara uygulamak için onlara unselectable adında bir sınıf atayabilir ve bu sınıf için bu kod tanımlamalarını yapabilirsiniz;

.unselectable {
	-moz-user-select: -moz-none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-o-user-select: none;
	-ms-user-select: none;
	user-select: none
}

IE9 ve Altı İçin Çözüm

CSS ile bir çözümünü bulamadım.. Ancak html niteliği ve javascript ile çözümleri mevcut.. Seçilemez olmasını istediğiniz nesneye unselectable=”on” eklemeniz yeterli olacaktır.

<div unselectable="on">
bu yazı artık ie9 ve altı için seçilemez hale geldi!
</div>

Ya da javascript ile yapmak istersek setAttribute() ile niteliği ekleyebiliriz.

<div id="nesne">
bu yazı artık ie9 ve altı için seçilemez hale geldi!
</div>
<script type="text/javascript">
document.getElementById("nesne").setAttribute("unselectable", "on");
</script>

Evet işte bu kadar, artık nesneler içerisindeki yazılar seçilemez oldu ????