Bu yazıda, kullanıcıların resimlerden metin çıkarıp, bu metni seçilen bir dile çevirebileceği bir OCR (Optical Character Recognition) ve çeviri uygulaması geliştireceğiz. Bu uygulama, görsellerden metin tanıyacak, ardından bu metni çevirecek ve kullanıcılara çevrilmiş metni gösterecek. Uygulamanın özellikleri arasında resim yükleme (sürükle-bırak), dil seçme ve metin kopyalama gibi işlevler yer alacak.
1. Gereksinimler ve Kurulum
Bu uygulamayı çalıştırmak için aşağıdaki Python kütüphanelerine ihtiyacınız olacak:
- Tkinter: GUI oluşturma
- Pillow: Resimleri işleme
- PaddleOCR: OCR işlemi yapma
- deep_translator: Çeviri yapma
- tkinterdnd2: Resim sürükleyip bırakma işlevselliği
- pyperclip: Çevrilen metni kopyalama
Tüm gereksinimleri kurmak için aşağıdaki gibi bir bat dosyası oluşturup çalıştırabilirsiniz:
@echo off
python --version >nul 2>&1
if %errorlevel% neq 0 (
echo Python bulunamadi, kurulum baslatiliyor...
echo Python 3.11.5 indiriliyor...
curl -o python-installer.exe https://www.python.org/ftp/python/3.11.5/python-3.11.5-amd64.exe
start /wait python-installer.exe /quiet InstallAllUsers=1 PrependPath=1
del python-installer.exe
echo Python kuruldu.
)
echo Pip guncelleniyor...
python -m pip install --upgrade pip
set "requirements=tkinter pillow paddleocr deep-translator tkinterdnd2 pyperclip"
for %%k in (%requirements%) do (
python -c "import %%k" >nul 2>&1
if %errorlevel% neq 0 (
echo %%k kutuphanesi bulunamadi, kurulum baslatiliyor...
python -m pip install %%k
)
)
echo Tum kutuphaneler kurulu. Uygulamayi calistirabilirsiniz.
pause
2. Uygulama Tasarımı
Uygulamamızda bir kullanıcı arayüzü (GUI) olacak ve bu arayüzde aşağıdaki bileşenler bulunacak:
- Görsel Yükleme: Kullanıcılar, desteklenen dosya formatlarında (JPG, PNG, BMP, vb.) bir görsel sürükleyip bırakabilecekler
- Dil Seçimi: Tanınan metnin hangi dilden çevrileceği ayarlanabilecek
- Metin Görüntüleme: Çıkarılan metin ve çevirisi ekranda gösterilecek
- Metin Kopyalama: Kullanıcılar, çevrilen metni kolayca kopyalayabilecekler
3. Kaynak Kod
Aşağıda, uygulamanın tüm kodunu bulabilirsiniz. Kodda detaylı açıklamalar yer almakta, böylece her adımı detaylıca inceleyebilirsiniz:
import tkinter as tk
from tkinter import ttk, messagebox
from PIL import Image, ImageTk
from paddleocr import PaddleOCR
from deep_translator import GoogleTranslator
import threading
from tkinterdnd2 import DND_FILES, TkinterDnD
import pyperclip
class FuturisticOCRTranslator:
"""
Fütüristik görünümlü OCR ve çeviri uygulaması.
Görüntülerden metin çıkarımı yapıp farklı dillere çeviri yapar.
"""
def __init__(self):
# Ana pencere ayarları
self.root = TkinterDnD.Tk()
self.root.title("OCR Çeviri")
self.root.geometry("1200x450")
self.root.configure(bg='#0a0a1f')
# Combobox stil ayarları
self.root.option_add('*TCombobox*Listbox.background', '#0a0a1f')
self.root.option_add('*TCombobox*Listbox.foreground', '#00ff8c')
self.root.option_add('*TCombobox*Listbox.selectBackground', '#1a1a3f')
self.root.option_add('*TCombobox*Listbox.selectForeground', '#00ff8c')
# Animasyon ve görüntü değişkenleri
self.border_color_index = 0
self.current_image = None
self.MAX_IMAGE_SIZE = (250, 200)
# Uygulama renk paleti
self.colors = {
'bg': '#0a0a1f',
'accent': '#00FF00',
'secondary': '#0066ff',
'text': '#00ff8c',
'border': '#00ccff',
'box_bg': '#0f0f2f',
'button_bg': '#1a1a3f'
}
# Ttk stil yapılandırması
self.style = ttk.Style()
self.style.theme_use('default')
self.configure_styles()
# Desteklenen diller sözlüğü
self.languages = {
'Türkçe': 'tr',
'İngilizce': 'en',
'Almanca': 'de',
'Fransızca': 'fr',
'İspanyolca': 'es',
'İtalyanca': 'it',
'Rusça': 'ru',
'Japonca': 'ja',
'Korece': 'ko',
'Çince': 'zh-CN'
}
self.setup_ui()
self.ocr = PaddleOCR(use_angle_cls=True, lang='en')
self.animate_borders()
def configure_styles(self):
"""Ttk bileşenleri için özel stillerin yapılandırılması"""
self.style.configure('Cyber.TFrame', background=self.colors['bg'])
self.style.configure('Cyber.TLabel',
background=self.colors['bg'],
foreground=self.colors['text'],
font=('Consolas', 11))
self.style.configure('CyberTitle.TLabel',
background=self.colors['bg'],
foreground=self.colors['accent'],
font=('Consolas', 24, 'bold'))
self.style.configure('CyberSubTitle.TLabel',
background=self.colors['bg'],
foreground='#888888',
font=('Consolas', 12))
self.style.map('TCombobox',
fieldbackground=[('readonly', self.colors['bg'])],
selectbackground=[('readonly', self.colors['bg'])],
selectforeground=[('readonly', self.colors['text'])],
background=[('readonly', self.colors['bg'])],
foreground=[('readonly', self.colors['text'])])
self.style.configure('TCombobox',
background=self.colors['bg'],
fieldbackground=self.colors['bg'],
foreground=self.colors['text'],
arrowcolor=self.colors['accent'],
selectbackground=self.colors['bg'],
selectforeground=self.colors['text'])
self.style.configure('Cyber.TButton',
background=self.colors['button_bg'],
foreground=self.colors['text'],
borderwidth=2,
font=('Consolas', 10))
def setup_ui(self):
"""Kullanıcı arayüzünün oluşturulması"""
self.main_frame = ttk.Frame(self.root, style='Cyber.TFrame')
self.main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
title_frame = ttk.Frame(self.main_frame, style='Cyber.TFrame')
title_frame.pack(fill=tk.X, pady=(0, 10))
title = ttk.Label(title_frame,
text="LEIDENFROST OCR ÇEVİRİ 🈯",
style='CyberTitle.TLabel')
title.pack()
subtitle = ttk.Label(title_frame,
text="Gelişmiş Görüntü Tanıma ve Çeviri Sistemi",
style='CyberSubTitle.TLabel')
subtitle.pack()
# Kontrol paneli
self.control_frame = ttk.Frame(self.main_frame, style='Cyber.TFrame')
self.control_frame.pack(fill=tk.X, pady=(0, 10))
# Dil seçimi
lang_frame = ttk.Frame(self.control_frame, style='Cyber.TFrame')
lang_frame.pack(pady=5)
ttk.Label(lang_frame, text="KAYNAK ⟶", style='Cyber.TLabel').pack(side=tk.LEFT, padx=(0, 10))
self.source_lang = ttk.Combobox(lang_frame,
values=['Otomatik'],
state='readonly',
style='TCombobox',
width=15)
self.source_lang.pack(side=tk.LEFT, padx=(0, 20))
self.source_lang.set('Otomatik')
ttk.Label(lang_frame, text="HEDEF ⟶", style='Cyber.TLabel').pack(side=tk.LEFT, padx=(0, 10))
self.target_lang = ttk.Combobox(lang_frame,
values=list(self.languages.keys()),
state='readonly',
style='TCombobox',
width=15)
self.target_lang.pack(side=tk.LEFT)
self.target_lang.set('Türkçe')
self.source_lang.bind('<<ComboboxSelected>>', lambda e: self.update_combobox_colors(self.source_lang))
self.target_lang.bind('<<ComboboxSelected>>', lambda e: self.update_combobox_colors(self.target_lang))
self.root.after(10, lambda: self.update_combobox_colors(self.source_lang))
self.root.after(10, lambda: self.update_combobox_colors(self.target_lang))
# İçerik bölümü
content_frame = ttk.Frame(self.main_frame, style='Cyber.TFrame')
content_frame.pack(fill=tk.BOTH, expand=True)
content_frame.grid_columnconfigure(0, weight=1)
content_frame.grid_columnconfigure(1, weight=1)
# Görüntü bölümü
self.image_frame = tk.Frame(content_frame, bg=self.colors['bg'])
self.image_frame.grid(row=0, column=0, sticky='nsew', padx=(0, 10))
# Animasyonlu kenarlıklar
self.border_frames = []
current_frame = self.image_frame
for i in range(3):
frame = tk.Frame(current_frame, bg=self.colors['border'])
frame.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
self.border_frames.append(frame)
current_frame = frame
# İç frame
self.inner_frame = tk.Frame(self.border_frames[-1], bg=self.colors['bg'])
self.inner_frame.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
self.image_container = ttk.Frame(self.inner_frame, style='Cyber.TFrame')
self.image_container.pack(fill=tk.BOTH, expand=True)
# Sürükle-bırak etiketi
self.drop_label = ttk.Label(
self.image_container,
text=(
"⤓ RESİM SÜRÜKLE BIRAK ⤓\n\n"
"Desteklenen formatlar: PNG, JPG, JPEG, BMP, GIF\n"
"WEBP, TIFF, TIF, HEIF, HEIC, RAW\n\n"
"Resme tıklayarak tam ekran görüntüle"
),
style='Cyber.TLabel'
)
self.drop_label.pack(fill=tk.BOTH, expand=True)
# Görüntü etiketi
self.image_label = ttk.Label(self.image_container, style='Cyber.TLabel')
# Temizle butonu
self.clear_button = tk.Button(self.inner_frame,
text="🗑 RESMİ TEMİZLE",
command=self.clear_image,
bg=self.colors['button_bg'],
fg=self.colors['text'],
activebackground=self.colors['accent'],
activeforeground=self.colors['bg'],
font=('Consolas', 10),
bd=0,
padx=10,
cursor='hand2')
# Sonuç bölümü
result_outer_frame = tk.Frame(content_frame, bg=self.colors['border'])
result_outer_frame.grid(row=0, column=1, sticky='nsew', padx=(10, 0))
self.result_frame = tk.Frame(result_outer_frame, bg=self.colors['box_bg'])
self.result_frame.pack(fill=tk.BOTH, expand=True, padx=2, pady=2)
text_header = tk.Frame(self.result_frame, bg=self.colors['box_bg'])
text_header.pack(fill=tk.X, padx=10, pady=5)
ttk.Label(text_header, text="Çeviri Sonucu:", style='Cyber.TLabel').pack(side=tk.LEFT)
# Kopyala butonu
copy_button = tk.Button(text_header,
text="📋 KOPYALA",
command=self.copy_text,
bg=self.colors['button_bg'],
fg=self.colors['text'],
activebackground=self.colors['accent'],
activeforeground=self.colors['bg'],
font=('Consolas', 10),
bd=0,
padx=10,
cursor='hand2')
copy_button.pack(side=tk.RIGHT)
# Sonuç metin alanı
self.text_label = tk.Text(self.result_frame,
wrap=tk.WORD,
font=('Consolas', 11),
bg=self.colors['box_bg'],
fg=self.colors['text'],
insertbackground=self.colors['text'],
selectbackground=self.colors['accent'],
selectforeground=self.colors['bg'],
bd=0,
height=10,
padx=10,
pady=10)
self.text_label.pack(fill=tk.BOTH, expand=True)
# Sürükle-bırak ve fare olayları
self.drop_label.drop_target_register(DND_FILES)
self.drop_label.dnd_bind('<<Drop>>', self.handle_drop)
self.inner_frame.bind('<Enter>', self.on_hover_enter)
self.inner_frame.bind('<Leave>', self.on_hover_leave)
def update_combobox_colors(self, combobox):
combobox.configure(
foreground=self.colors['text'],
background=self.colors['bg']
)
def clear_image(self):
self.current_image = None
self.image_label.pack_forget()
self.drop_label.pack(fill=tk.BOTH, expand=True)
self.clear_button.pack_forget()
self.text_label.delete(1.0, tk.END)
def copy_text(self):
text = self.text_label.get(1.0, tk.END).strip()
pyperclip.copy(text)
temp_label = tk.Label(self.result_frame,
text="✓ Kopyalandı!",
fg=self.colors['accent'],
bg=self.colors['box_bg'],
font=('Consolas', 10))
temp_label.place(relx=1, rely=0, anchor='ne')
self.root.after(1000, temp_label.destroy)
def animate_borders(self):
colors = ['#00ccff', '#00ff8c', '#0066ff', '#ff00ff']
for i, frame in enumerate(self.border_frames):
new_color = colors[(i + self.border_color_index) % len(colors)]
frame.configure(bg=new_color)
self.border_color_index = (self.border_color_index + 1) % len(colors)
self.root.after(1000, self.animate_borders)
def on_hover_enter(self, event):
self.drop_label.configure(foreground=self.colors['accent'])
def on_hover_leave(self, event):
self.drop_label.configure(foreground=self.colors['text'])
def handle_drop(self, event):
file_paths = event.data.split()
if len(file_paths) > 1:
messagebox.showerror("Hata", "Lütfen aynı anda sadece bir resim sürükleyin!")
return
file_path = file_paths[0]
if file_path.startswith('{'):
file_path = file_path[1:-1]
if not file_path.lower().endswith((
'.png', '.jpg', '.jpeg', '.bmp', '.gif', '.webp',
'.tiff', '.tif', '.heif', '.heic', '.raw'
)):
messagebox.showerror("Hata", "Lütfen geçerli bir resim dosyası seçin!")
return
try:
Image.open(file_path)
except:
messagebox.showerror("Hata", "Seçilen dosya geçerli bir resim değil!")
return
self.display_image(file_path)
self.process_image(file_path)
def display_image(self, file_path):
self.drop_label.pack_forget()
self.current_image = Image.open(file_path)
display_size = self.calculate_display_size(self.current_image)
image = self.current_image.resize(display_size, Image.Resampling.LANCZOS)
photo = ImageTk.PhotoImage(image)
self.image_label.configure(image=photo)
self.image_label.image = photo
self.image_label.pack(expand=True)
self.clear_button.pack(pady=5)
def calculate_display_size(self, image):
max_width, max_height = self.MAX_IMAGE_SIZE
width, height = image.size
aspect_ratio = width / height
if width > max_width or height > max_height:
if aspect_ratio > max_width / max_height:
new_width = max_width
new_height = int(max_width / aspect_ratio)
else:
new_height = max_height
new_width = int(max_height * aspect_ratio)
else:
new_width, new_height = width, height
return (new_width, new_height)
def process_image(self, file_path):
"""OCR ve çeviri işlemini gerçekleştirme"""
def process():
try:
self.text_label.delete(1.0, tk.END)
self.text_label.insert(tk.END, "İşleniyor...\n")
# OCR
result = self.ocr.ocr(file_path, cls=True)
extracted_text = '\n'.join([line[1][0] for line in result[0]])
# Çeviri
target = self.languages[self.target_lang.get()]
translator = GoogleTranslator(source='auto', target=target)
translated_text = translator.translate(extracted_text)
self.text_label.delete(1.0, tk.END)
self.text_label.insert(tk.END, translated_text)
except Exception as e:
messagebox.showerror("Hata", f"İşlem sırasında bir hata oluştu: {str(e)}")
self.text_label.delete(1.0, tk.END)
self.text_label.insert(tk.END, "İşlem sırasında hata oluştu.")
threading.Thread(target=process, daemon=True).start()
def run(self):
self.root.mainloop()
if __name__ == "__main__":
app = FuturisticOCRTranslator()
app.run()
4. Uygulama Ekran Görüntüsü

Sonuç
PaddleOCR ve DeepTranslator kütüphanesinin gücünü kullanan bu uygulama, özellikle çok dilli belge işleme, yabancı dildeki metinleri hızlıca anlama ve dijital içerik çevirisi gibi ihtiyaçlar için kullanışlı bir araç sunuyor. Açık kaynak kodlu bu projeyi kendi ihtiyaçlarınıza göre özelleştirebilir, geliştirebilir ve farklı projelerinize entegre edebilirsiniz.