diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index f16121afabc4794832b931bbb436feb70fa85a98..13efa4ec58b5b1ab65b2749450040bb47b7fa78d 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -567,6 +567,32 @@ def _add_functionality():
 
     # }}}
 
+    # {{{ ImageFormat
+
+    def image_format_repr(self):
+        return "ImageFormat(%s, %s)" % (
+                channel_order.to_string(self.channel_order,
+                    "<unknown channel order 0x%x>"),
+                channel_type.to_string(self.channel_data_type,
+                    "<unknown channel data type 0x%x>"))
+
+    def image_format_eq(self, other):
+        return (self.channel_order == other.channel_order
+                and self.channel_data_type == other.channel_data_type)
+
+    def image_format_ne(self, other):
+        return not image_format_eq(self, other)
+
+    def image_format_hash(self):
+        return hash((type(self), self.channel_order, self.channel_data_type))
+
+    ImageFormat.__repr__ = image_format_repr
+    ImageFormat.__eq__ = image_format_eq
+    ImageFormat.__ne__ = image_format_ne
+    ImageFormat.__hash__ = image_format_hash
+
+    # }}}
+
     # {{{ Image
 
     image_old_init = Image.__init__
@@ -670,8 +696,17 @@ def _add_functionality():
             else:
                 return self.event.get_image_info(inf_attr)
 
+    def image_shape(self):
+        if self.type == mem_object_type.IMAGE2D:
+            return (self.width, self.height)
+        elif self.type == mem_object_type.IMAGE3D:
+            return (self.width, self.height, self.depth)
+        else:
+            raise LogicError("only images have shapes")
+
     Image.__init__ = image_init
     Image.image = property(_ImageInfoGetter)
+    Image.shape = property(image_shape)
 
     # }}}
 
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index aca699344900b021bd688446a47b8a2280f4d735..0cbdea29f27df26443299e61228d7ccd6e435eae 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -1515,23 +1515,6 @@ class ImageFormat(object):
     def itemsize(self):
         return self.channel_count * self.dtype_size
 
-    def __repr__(self):
-        return "ImageFormat(%s, %s)" % (
-                channel_order.to_string(self.channel_order,
-                    "<unknown channel order 0x%x>"),
-                channel_type.to_string(self.channel_data_type,
-                    "<unknown channel data type 0x%x>"))
-
-    def __eq__(self, other):
-        return (self.channel_order == other.channel_order
-                and self.channel_data_type == other.channel_data_type)
-
-    def __ne__(self, other):
-        return not self.__eq__(self, other)
-
-    def __hash__(self):
-        return hash((ImageFormat, self.channel_order, self.channel_data_type))
-
 
 def get_supported_image_formats(context, flags, image_type):
     info = _ffi.new('generic_info*')
@@ -1696,16 +1679,6 @@ class Image(MemoryObject):
         _handle_error(_lib.image__get_image_info(self.ptr, param, info))
         return _generic_info_to_python(info)
 
-    @property
-    def shape(self):
-        if self.type == mem_object_type.IMAGE2D:
-            return (self.width, self.height)
-        elif self.type == mem_object_type.IMAGE3D:
-            return (self.width, self.height, self.depth)
-        else:
-            raise LogicError("only images have shapes",
-                             status_code.INVALID_VALUE, "Image")
-
 # }}}