gui/artwork: Fix blurry album art
Using gdk_pixbuf_new_from_file_at_scale() can result in a blurry image due to something in the gdk backend. I want to have a sharper image, so we need to perform the scale manually through Cairo. Fixes issue #60: Album art is blurry Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
7dff5412bc
commit
343dec5d8d
|
@ -1,4 +1,5 @@
|
||||||
6.4.16:
|
6.4.16:
|
||||||
|
- Fix blurry album art
|
||||||
- Reduce time spent polling for album art
|
- Reduce time spent polling for album art
|
||||||
- Split album art code into a new file
|
- Split album art code into a new file
|
||||||
- Fix PKGBUILD dependencies
|
- Fix PKGBUILD dependencies
|
||||||
|
|
|
@ -8,42 +8,69 @@
|
||||||
static struct album *__artwork_cur_album = NULL;
|
static struct album *__artwork_cur_album = NULL;
|
||||||
static unsigned int __artwork_timeo_id = 0;
|
static unsigned int __artwork_timeo_id = 0;
|
||||||
|
|
||||||
static GdkPixbuf *__artwork_get_pixbuf(struct track *track)
|
static cairo_surface_t *__artwork_scale_pixbuf(GdkPixbuf *pix)
|
||||||
|
{
|
||||||
|
int old_h = gdk_pixbuf_get_height(pix);
|
||||||
|
int old_w = gdk_pixbuf_get_width(pix);
|
||||||
|
int new_h = gui_builder_widget_height("o_position") +
|
||||||
|
gui_builder_widget_height("o_tags");
|
||||||
|
int new_w = (old_w * new_h) / old_h;
|
||||||
|
int scale = gtk_widget_get_scale_factor(gui_builder_widget("o_cover"));
|
||||||
|
cairo_surface_t *orig = gdk_cairo_surface_create_from_pixbuf(pix, 0,
|
||||||
|
NULL);
|
||||||
|
cairo_content_t content = cairo_surface_get_content(orig);
|
||||||
|
cairo_surface_t *new = cairo_surface_create_similar(orig, content,
|
||||||
|
new_w, new_h);
|
||||||
|
cairo_t *cairo = cairo_create(new);
|
||||||
|
|
||||||
|
cairo_scale(cairo, (double)(scale * new_w) / old_w,
|
||||||
|
(double)(scale * new_h) / old_h);
|
||||||
|
cairo_set_source_surface(cairo, orig, 0, 0);
|
||||||
|
cairo_paint(cairo);
|
||||||
|
|
||||||
|
cairo_destroy(cairo);
|
||||||
|
cairo_surface_destroy(orig);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *__artwork_get_surface(struct track *track)
|
||||||
{
|
{
|
||||||
gchar *path = album_artwork_path(track->tr_album);
|
gchar *path = album_artwork_path(track->tr_album);
|
||||||
|
cairo_surface_t *surface;
|
||||||
GdkPixbuf *pix;
|
GdkPixbuf *pix;
|
||||||
int height;
|
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
height = gui_builder_widget_height("o_position") +
|
pix = gdk_pixbuf_new_from_file(path, NULL);
|
||||||
gui_builder_widget_height("o_tags");
|
if (!pix)
|
||||||
pix = gdk_pixbuf_new_from_file_at_scale(path, -1, height, true, NULL);
|
return NULL;
|
||||||
g_free(path);
|
surface = __artwork_scale_pixbuf(pix);
|
||||||
|
|
||||||
return pix;
|
g_object_unref(G_OBJECT(pix));
|
||||||
|
g_free(path);
|
||||||
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool __artwork_set_pixbuf(void)
|
static bool __artwork_set_pixbuf(void)
|
||||||
{
|
{
|
||||||
GtkImage *cover = GTK_IMAGE(gui_builder_widget("o_cover"));
|
GtkImage *cover = GTK_IMAGE(gui_builder_widget("o_cover"));
|
||||||
struct track *track = audio_cur_track();
|
struct track *track = audio_cur_track();
|
||||||
GdkPixbuf *pix;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
if (!track || track->tr_album == __artwork_cur_album)
|
if (!track || track->tr_album == __artwork_cur_album)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
pix = __artwork_get_pixbuf(track);
|
surface = __artwork_get_surface(track);
|
||||||
if (pix) {
|
if (surface) {
|
||||||
gtk_image_set_from_pixbuf(cover, pix);
|
gtk_image_set_from_surface(cover, surface);
|
||||||
g_object_unref(G_OBJECT(pix));
|
cairo_surface_destroy(surface);
|
||||||
} else
|
} else
|
||||||
gtk_image_set_from_icon_name(cover, "image-missing", GTK_ICON_SIZE_DIALOG);
|
gtk_image_set_from_icon_name(cover, "image-missing", GTK_ICON_SIZE_DIALOG);
|
||||||
|
|
||||||
gtk_widget_set_sensitive(GTK_WIDGET(cover), pix != NULL);
|
gtk_widget_set_sensitive(GTK_WIDGET(cover), surface != NULL);
|
||||||
__artwork_cur_album = pix ? track->tr_album : NULL;
|
__artwork_cur_album = surface ? track->tr_album : NULL;
|
||||||
return (pix != NULL);
|
return (surface != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean __artwork_timeout(gpointer data)
|
static gboolean __artwork_timeout(gpointer data)
|
||||||
|
|
Loading…
Reference in New Issue