diff --git a/contrib/danbooru_api/main.php b/contrib/danbooru_api/main.php
index 477d4e3e..342c4d66 100644
--- a/contrib/danbooru_api/main.php
+++ b/contrib/danbooru_api/main.php
@@ -205,7 +205,7 @@ class DanbooruApi implements Extension
 				// It is also currently broken due to some confusion over file variable ($tmp_filename?)
 				
 				// Does it exist already?
-				$existing = $database->get_image_by_hash($hash);
+				$existing = Image::by_hash($config, $database, $hash);
 				if(!is_null($existing)) {
 					header("HTTP/1.0 409 Conflict");
 					header("X-Danbooru-Errors: duplicate");
@@ -229,7 +229,7 @@ class DanbooruApi implements Extension
 					return;
 				} else
 				{	// If it went ok, grab the id for the newly uploaded image and pass it in the header
-					$newimg = $database->get_image_by_hash($hash);
+					$newimg = Image::by_hash($config, $database, $hash);
 					$newid = make_link("post/view/" . $newimg->id);
 					// Did we POST or GET this call?
 					if($_SERVER['REQUEST_METHOD'] == 'POST')
@@ -265,21 +265,21 @@ class DanbooruApi implements Extension
 				$md5list = explode(",",$_GET['md5']);
 				foreach($md5list as $md5)
 				{
-					$results[] = $database->get_image_by_hash($md5);
+					$results[] = Image::by_hash($config, $database, $md5);
 				}
 			} elseif(isset($_GET['id']))
 			{
 				$idlist = explode(",",$_GET['id']);
 				foreach($idlist as $id)
 				{
-					$results[] = $database->get_image($id);
+					$results[] = Image::by_id($config, $database, $id);
 				}
 			} else
 			{
 				$limit = isset($_GET['limit']) ? int_escape($_GET['limit']) : 100;
 				$start = isset($_GET['offset']) ? int_escape($_GET['offset']) : 0;
 				$tags = isset($_GET['tags']) ? tag_explode($_GET['tags']) : array();
-				$results = $database->get_images($start,$limit,$tags);
+				$results = Image::find_images($config,$database,$start,$limit,$tags);
 			}
 			
 			// Now we have the array $results filled with Image objects
diff --git a/contrib/handle_ico/main.php b/contrib/handle_ico/main.php
index 344c3737..2a6c89a4 100644
--- a/contrib/handle_ico/main.php
+++ b/contrib/handle_ico/main.php
@@ -39,9 +39,10 @@ class IcoFileHandler implements Extension {
 		}
 
 		if(($event instanceof PageRequestEvent) && $event->page_matches("get_ico")) {
+			global $config;
 			global $database;
 			$id = int_escape($event->get_arg(0));
-			$image = $database->get_image($id);
+			$image = Image::by_id($config, $database, $id);
 			$hash = $image->hash;
 			$ha = substr($hash, 0, 2);
 			
diff --git a/contrib/handle_svg/main.php b/contrib/handle_svg/main.php
index 3941b5a4..483f7657 100644
--- a/contrib/handle_svg/main.php
+++ b/contrib/handle_svg/main.php
@@ -49,9 +49,10 @@ class SVGFileHandler implements Extension {
 		}
 		
 		if(($event instanceof PageRequestEvent) && $event->page_matches("get_svg")) {
+			global $config;
 			global $database;
 			$id = int_escape($event->get_arg(0));
-			$image = $database->get_image($id);
+			$image = Image::by_id($config, $database, $id);
 			$hash = $image->hash;
 			$ha = substr($hash, 0, 2);
 			
diff --git a/contrib/image_hash_ban/main.php b/contrib/image_hash_ban/main.php
index baeaeb0e..ad275dd0 100644
--- a/contrib/image_hash_ban/main.php
+++ b/contrib/image_hash_ban/main.php
@@ -63,8 +63,9 @@ class ImageBan implements Extension {
 						$page->set_redirect(make_link("admin"));
 					}
 					if(isset($_POST['image_id'])) {
+						global $config;
 						global $database;
-						$image = $database->get_image($_POST['image_id']);
+						$image = Image::by_id($config, $database, int_escape($_POST['image_id']));
 						if($image) {
 							send_event(new ImageDeletionEvent($image));
 							$event->page->set_mode("redirect");
diff --git a/contrib/random_image/main.php b/contrib/random_image/main.php
index 962fec35..a58e82df 100644
--- a/contrib/random_image/main.php
+++ b/contrib/random_image/main.php
@@ -11,6 +11,7 @@ class RandomImage implements Extension {
 	public function receive_event(Event $event) {
 		if(($event instanceof PageRequestEvent) && $event->page_matches("random_image")) {
 			global $database;
+			global $database;
 			
 			if($event->count_args() == 1) {
 				$action = $event->get_arg(0);
@@ -20,7 +21,7 @@ class RandomImage implements Extension {
 				$action = $event->get_arg(0);
 				$search_terms = explode(' ', $event->get_arg(1));
 			}
-			$image = $database->get_random_image($search_terms);
+			$image = Image::by_random($config, $database, $search_terms);
 
 			if($event->get_arg(0) == "download") {
 				if(!is_null($image)) {
diff --git a/contrib/regen_thumb/main.php b/contrib/regen_thumb/main.php
index ff968ddd..0b312396 100644
--- a/contrib/regen_thumb/main.php
+++ b/contrib/regen_thumb/main.php
@@ -15,8 +15,9 @@ class RegenThumb implements Extension {
 		if(($event instanceof PageRequestEvent) && $event->page_matches("regen_thumb")) {
 			global $user;
 			if($user->is_admin() && isset($_POST['image_id'])) {
+				global $config;
 				global $database;
-				$image = $database->get_image(int_escape($_POST['image_id']));
+				$image = Image::by_id($config, $database, int_escape($_POST['image_id']));
 				send_event(new ThumbnailGenerationEvent($image->hash, $image->ext));
 				$this->theme->display_results($event->page, $image);
 			}
diff --git a/contrib/rss_images/main.php b/contrib/rss_images/main.php
index ff681157..a10ac660 100644
--- a/contrib/rss_images/main.php
+++ b/contrib/rss_images/main.php
@@ -27,12 +27,13 @@ class RSS_Images implements Extension {
 
 		if(($event instanceof PageRequestEvent) && $event->page_matches("rss")) {
 			if($event->get_arg(0) == 'images') {
+				global $config;
 				global $database;
 				if($event->count_args() >= 2) {
-					$this->do_rss($database->get_images(0, 12, tag_explode($event->get_arg(1))));
+					$this->do_rss(Image::find_images($config, $database, 0, 12, tag_explode($event->get_arg(1))));
 				}
 				else {
-					$this->do_rss($database->get_images(0, 12));
+					$this->do_rss(image::find_images($config, $database, 0, 12));
 				}
 			}
 		}
diff --git a/core/database.class.php b/core/database.class.php
index 096f3c7b..16ebd277 100644
--- a/core/database.class.php
+++ b/core/database.class.php
@@ -418,87 +418,5 @@ class Database {
 		$this->execute("UPDATE images SET source=? WHERE id=?", array($source, $image_id));
 	}
 // }}}
-// images {{{
-	public function get_images($start, $limit, $tags=array()) {
-		$images = array();
-
-		assert(is_numeric($start) && $start >= 0);
-		assert(is_numeric($limit) && $limit >  0);
-		if($start < 0) $start = 0;
-		if($limit < 1) $limit = 1;
-		
-		if(count($tags) == 0) {
-			$result = $this->execute("SELECT images.* FROM images ORDER BY id DESC LIMIT ? OFFSET ?", array($limit, $start));
-		}
-		else {
-			$querylet = $this->build_search_querylet($tags);
-			$querylet->append(new Querylet("ORDER BY images.id DESC LIMIT ? OFFSET ?", array($limit, $start)));
-			$result = $this->execute($querylet->sql, $querylet->variables);
-		}
-		
-		while(!$result->EOF) {
-			$images[] = new Image($result->fields);
-			$result->MoveNext();
-		}
-		return $images;
-	}
-
-	public function get_next_image($id, $tags=array(), $next=true) {
-		assert(is_numeric($id));
-		assert(is_array($tags));
-		assert(is_bool($next));
-		
-		if($next) {
-			$gtlt = "<";
-			$dir = "DESC";
-		}
-		else {
-			$gtlt = ">";
-			$dir = "ASC";
-		}
-
-		if(count($tags) == 0) {
-			$row = $this->db->GetRow("SELECT images.* FROM images WHERE images.id $gtlt ? ORDER BY images.id $dir LIMIT 1", array((int)$id));
-		}
-		else {
-			$tags[] = "id$gtlt$id";
-			$querylet = $this->build_search_querylet($tags);
-			$querylet->append_sql(" ORDER BY images.id $dir LIMIT 1");
-			$row = $this->db->GetRow($querylet->sql, $querylet->variables);
-		}
-		
-		return ($row ? new Image($row) : null);
-	}
-
-	public function get_prev_image($id, $tags=array()) {
-		return $this->get_next_image($id, $tags, false);
-	}
-
-	public function get_image($id) {
-		assert(is_numeric($id));
-		$image = null;
-		$row = $this->db->GetRow("SELECT images.* FROM images WHERE images.id=?", array($id));
-		return ($row ? new Image($row) : null);
-	}
-
-	public function get_random_image($tags=array()) {
-		$max = $this->count_images($tags);
-		$rand = mt_rand(0, $max);
-		$set = $this->get_images($rand, 1, $tags);
-		if(count($set) > 0) return $set[0];
-		else return null;
-	}
-
-	public function get_image_by_hash($hash) {
-		assert(is_string($hash));
-		$image = null;
-		$row = $this->db->GetRow("SELECT images.* FROM images WHERE hash=?", array($hash));
-		return ($row ? new Image($row) : null);
-	}
-
-	public function remove_image($id) {
-		$this->execute("DELETE FROM images WHERE id=?", array($id));
-	}
-// }}}
 }
 ?>
diff --git a/core/image.class.php b/core/image.class.php
index 3d685331..d68e0e4c 100644
--- a/core/image.class.php
+++ b/core/image.class.php
@@ -39,6 +39,76 @@ class Image {
 		return ($row ? new Image($row) : null);
 	}
 	
+	public static function by_hash(Config $config, Database $database, $hash) {
+		assert(is_string($hash));
+		$image = null;
+		$row = $this->db->GetRow("SELECT images.* FROM images WHERE hash=?", array($hash));
+		return ($row ? new Image($row) : null);
+	}
+
+	public static function by_random(Config $config, Database $database, $tags=array()) {
+		$max = $database->count_images($tags);
+		$rand = mt_rand(0, $max);
+		$set = Image::find_images($config, $database, $rand, 1, $tags);
+		if(count($set) > 0) return $set[0];
+		else return null;
+	}
+	
+	public static function find_images(Config $config, Database $database, $start, $limit, $tags=array()) {
+		$images = array();
+
+		assert(is_numeric($start) && $start >= 0);
+		assert(is_numeric($limit) && $limit >  0);
+		if($start < 0) $start = 0;
+		if($limit < 1) $limit = 1;
+		
+		if(count($tags) == 0) {
+			$result = $database->execute("SELECT images.* FROM images ORDER BY id DESC LIMIT ? OFFSET ?", array($limit, $start));
+		}
+		else {
+			$querylet = $database->build_search_querylet($tags);
+			$querylet->append(new Querylet("ORDER BY images.id DESC LIMIT ? OFFSET ?", array($limit, $start)));
+			$result = $database->execute($querylet->sql, $querylet->variables);
+		}
+		
+		while(!$result->EOF) {
+			$images[] = new Image($result->fields);
+			$result->MoveNext();
+		}
+		return $images;
+	}
+
+
+	public function get_next($tags=array(), $next=true) {
+		assert(is_array($tags));
+		assert(is_bool($next));
+		
+		if($next) {
+			$gtlt = "<";
+			$dir = "DESC";
+		}
+		else {
+			$gtlt = ">";
+			$dir = "ASC";
+		}
+
+		if(count($tags) == 0) {
+			$row = $this->db->GetRow("SELECT images.* FROM images WHERE images.id $gtlt {$this->id} ORDER BY images.id $dir LIMIT 1");
+		}
+		else {
+			$tags[] = "id$gtlt{$this->id}";
+			$querylet = $this->database->build_search_querylet($tags);
+			$querylet->append_sql(" ORDER BY images.id $dir LIMIT 1");
+			$row = $this->db->GetRow($querylet->sql, $querylet->variables);
+		}
+		
+		return ($row ? new Image($row) : null);
+	}
+
+	public function get_prev($tags=array()) {
+		return $this->get_next($tags, false);
+	}
+	
 	public function delete() {
 		$this->database->execute("DELETE FROM images WHERE id=?", array($this->id));
 		
diff --git a/ext/image/main.php b/ext/image/main.php
index cca1bdde..08ffa86a 100644
--- a/ext/image/main.php
+++ b/ext/image/main.php
@@ -96,7 +96,7 @@ class ImageIO implements Extension {
 		/*
 		 * Check for an existing image
 		 */
-		$existing = $database->get_image_by_hash($image->hash);
+		$existing = Image::by_hash($config, $database, $image->hash);
 		if(!is_null($existing)) {
 			$handler = $config->get_string("upload_collision_handler");
 			if($handler == "merge") {
diff --git a/ext/index/main.php b/ext/index/main.php
index bb67bac4..0b60b2c2 100644
--- a/ext/index/main.php
+++ b/ext/index/main.php
@@ -56,7 +56,7 @@ class Index implements Extension {
 
 			$total_pages = $database->count_pages($search_terms);
 			$count = $config->get_int('index_width') * $config->get_int('index_height');
-			$images = $database->get_images(($page_number-1)*$count, $count, $search_terms);
+			$images = Image::find_images($config, $database, ($page_number-1)*$count, $count, $search_terms);
 
 			send_event(new PostListBuildingEvent($event->page, $search_terms));
 			
diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 156af4fd..814faff4 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -190,7 +190,7 @@ class TagList implements Extension {
 			if($n%3==0) $html .= "<tr>";
 			$h_tag = html_escape($row['tag']);
 			$link = $this->tag_link($row['tag']);
-			$image = $database->get_random_image(array($row['tag']));
+			$image = Image::by_random($config, $database, array($row['tag']));
 			$thumb = $image->get_thumb_link();
 			$html .= "<td><a href='$link'><img src='$thumb'><br>$h_tag</a></td>\n";
 			if($n%3==2) $html .= "</tr>";
diff --git a/ext/view/main.php b/ext/view/main.php
index a7595ecb..446d0cce 100644
--- a/ext/view/main.php
+++ b/ext/view/main.php
@@ -49,7 +49,8 @@ class ViewImage implements Extension {
 			$image_id = int_escape($event->get_arg(0));
 			
 			global $database;
-			$image = $database->get_image($image_id);
+			global $config;
+			$image = Image::by_id($config, $database, $image_id);
 
 			if(!is_null($image)) {
 				send_event(new DisplayingImageEvent($image, $event->page));
diff --git a/ext/view/theme.php b/ext/view/theme.php
index dd37a5f8..394ca9e5 100644
--- a/ext/view/theme.php
+++ b/ext/view/theme.php
@@ -9,7 +9,7 @@ class ViewImageTheme extends Themelet {
 		$page->set_heading(html_escape($image->get_tag_list()));
 		$page->add_block(new Block("Navigation", $this->build_navigation($image->id), "left", 0));
 		$page->add_block(new Block(null, $this->build_info($image, $editor_parts), "main", 10));
-		$page->add_block(new Block(null, $this->build_pin($image->id), "main", 11));
+		$page->add_block(new Block(null, $this->build_pin($image), "main", 11));
 	}
 
 	public function display_admin_block($page, $parts) {
@@ -21,7 +21,7 @@ class ViewImageTheme extends Themelet {
 
 	var $pin = null;
 
-	protected function build_pin($image_id) {
+	protected function build_pin($image) {
 		if(!is_null($this->pin)) {
 			return $this->pin;
 		}
@@ -37,8 +37,8 @@ class ViewImageTheme extends Themelet {
 			$query = null;
 		}
 		
-		$next = $database->get_next_image($image_id, $search_terms);
-		$prev = $database->get_prev_image($image_id, $search_terms);
+		$next = $image->get_next($search_terms);
+		$prev = $image->get_prev($search_terms);
 
 		$h_prev = (!is_null($prev) ? "<a href='".make_link("post/view/{$prev->id}", $query)."'>Prev</a>" : "Prev");
 		$h_index = "<a href='".make_link()."'>Index</a>";