diff --git a/picture.go b/picture.go
new file mode 100644
index 0000000000000000000000000000000000000000..fabfd6a3ad43c6b83f9328f67ba9f9b4ebb909cd
--- /dev/null
+++ b/picture.go
@@ -0,0 +1,73 @@
+package pixel
+
+import (
+	"image"
+	"image/draw"
+
+	"github.com/faiface/pixel/pixelgl"
+	"github.com/pkg/errors"
+)
+
+// Picture is a raster picture. It is usually used with sprites.
+//
+// A picture is created from an image.Image, that can be either loaded from a file, or generated. After the creation
+// a picture can be sliced (slicing creates a "sub-picture" from a picture) into smaller pictures.
+//
+// However note, that all of the sliced pictures share the same underlying texture. Deleting one picture also deletes
+// all pictures that share the same underlying texture.
+type Picture struct {
+	texture *pixelgl.Texture
+	bounds  Rect
+}
+
+// NewPicture creates a new picture from an image.Image.
+func NewPicture(img image.Image) Picture {
+	// convert the image to RGBA format
+	rgba := image.NewRGBA(image.Rect(0, 0, img.Bounds().Dx(), img.Bounds().Dy()))
+	draw.Draw(rgba, rgba.Bounds(), img, img.Bounds().Min, draw.Src)
+
+	texture, err := pixelgl.NewTexture(
+		pixelgl.NoOpDoer,
+		img.Bounds().Dx(),
+		img.Bounds().Dy(),
+		rgba.Pix,
+	)
+	if err != nil {
+		panic(errors.Wrap(err, "failed to create picture"))
+	}
+
+	return Picture{
+		texture: texture,
+		bounds:  R(0, 0, float64(texture.Width()), float64(texture.Height())),
+	}
+}
+
+// Delete deletes this picture and all pictures that share the same underlying texuture (all that have been
+// created from the same parent using slicing).
+func (p Picture) Delete() {
+	p.texture.Delete()
+}
+
+// Texture returns a pointer to the underlying OpenGL texture of a picture.
+func (p Picture) Texture() *pixelgl.Texture {
+	return p.texture
+}
+
+// Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture
+// share the same texture. Thus deleting one also deletes the other one.
+//
+// For example, suppose we have a 100x200 pixels picture. If we slice it with rectangle (50, 100, 50, 100), we get
+// the upper-right quadrant of the original picture.
+func (p Picture) Slice(slice Rect) Picture {
+	return Picture{
+		texture: p.texture,
+		bounds:  Rect{p.bounds.Pos + slice.Pos, slice.Size},
+	}
+}
+
+// Bounds returns the bounding rectangle of this picture relative to the most original picture.
+//
+// If the original picture gets sliced with the return value of this method, this picture will be obtained.
+func (p Picture) Bounds() Rect {
+	return p.bounds
+}