{"id":2589,"date":"2021-06-10T13:40:41","date_gmt":"2021-06-10T11:40:41","guid":{"rendered":"https:\/\/www.vikingsoftware.com\/uncategorized-da\/qlinear-gradient-strikes-back\/"},"modified":"2021-06-10T13:40:41","modified_gmt":"2021-06-10T11:40:41","slug":"qlinear-gradient-strikes-back","status":"publish","type":"post","link":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/","title":{"rendered":"QLinearGradient strikes back"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"2589\" class=\"elementor elementor-2589 elementor-835\" data-elementor-post-type=\"post\">\n\t\t\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-4d398c0 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"4d398c0\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-d7cf374\" data-id=\"d7cf374\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-75b289d elementor-widget elementor-widget-text-editor\" data-id=\"75b289d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><em>A long time ago I created a tool to help me in generating the gradient C++ code out of a raster image. Then I lost it, and last year I created it again. To make sure I didn&#8217;t lose it again, and in the hopes that other developers don&#8217;t have to create it too, I hereby share it with you.&nbsp;&nbsp;<\/em><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-97e12b0 elementor-widget elementor-widget-text-editor\" data-id=\"97e12b0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<pre><strong>Written by Denis Gofman<\/strong><br \/><strong>2021\/06\/11<\/strong><\/pre>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7422b5d elementor-widget elementor-widget-text-editor\" data-id=\"7422b5d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2><span style=\"font-weight: 400;\">What do the images below have in common?<\/span><\/h2>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b842833 elementor-widget elementor-widget-image-gallery\" data-id=\"b842833\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image-gallery.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-gallery\">\n\t\t\t<div class=\"wpmf-gallerys wpmf-gallerys-life \" ><div id=\"gallery-1\" class=\"gallery gallery_life wpmf_gallery_default gallery_default  gallery-columns-3 gallery-size-full gallery-link-file wpmf-has-border-radius-0 wpmf-gutterwidth-5 no_ratio\"><figure class=\"wpmf-gallery-item\" data-index=\"0\"><div class=\"wpmf-gallery-icon\"><div class=\"square_thumbnail\"><div class=\"img_centered\"><a class=\" not_video noLightbox\" data-lightbox=\"1\" data-href=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-1.jpg\" title=\"3pics 1\" target=\"_self\" data-index=\"0\"><img decoding=\"async\" class=\"wpmf_img\" alt=\"3pics 1\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-1.jpg\" data-type=\"wpmfgalleryimg\" data-lazy-src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-1.jpg\"><\/a><\/div><\/div><\/div><\/figure><figure class=\"wpmf-gallery-item\" data-index=\"1\"><div class=\"wpmf-gallery-icon\"><div class=\"square_thumbnail\"><div class=\"img_centered\"><a class=\" not_video noLightbox\" data-lightbox=\"1\" data-href=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-2.jpg\" title=\"3pics 2\" target=\"_self\" data-index=\"1\"><img decoding=\"async\" class=\"wpmf_img\" alt=\"3pics 2\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-2.jpg\" data-type=\"wpmfgalleryimg\" data-lazy-src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-2.jpg\"><\/a><\/div><\/div><\/div><\/figure><figure class=\"wpmf-gallery-item\" data-index=\"2\"><div class=\"wpmf-gallery-icon\"><div class=\"square_thumbnail\"><div class=\"img_centered\"><a class=\" not_video noLightbox\" data-lightbox=\"1\" data-href=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-3.jpg\" title=\"3pics 3\" target=\"_self\" data-index=\"2\"><img decoding=\"async\" class=\"wpmf_img\" alt=\"3pics 3\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-3.jpg\" data-type=\"wpmfgalleryimg\" data-lazy-src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-3.jpg\"><\/a><\/div><\/div><\/div><\/figure><\/div><\/div>\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-f6b87b1 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"f6b87b1\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-6d254b8\" data-id=\"6d254b8\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-8e5e802 elementor-widget elementor-widget-text-editor\" data-id=\"8e5e802\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Honestly, I hate questions like that, because there are a lot of formally correct answers: They all are rectangular, coded in the same format and shot by the same person (me) in the same location, and so on. But what definitely makes this question annoying is that I obviously, considering the title, want the answer to be: <em>gradients<\/em>.<\/span><\/p><p><span style=\"font-weight: 400;\">The analog world around us has almost no clean colors; it is filled by millions of shades in gradients. While the gradient can be interpreted as the \u00abdirection and rate of fastest change\u00bb, the digital world needs a more detailed and digital-related description. One may want to check the Wikipedia for a general definition and all that <\/span><strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Gradient\">scalar-valued differentiable function F of several variables<\/a><\/strong><span style=\"font-weight: 400;\"> stuff, but here I will cover only necessary graphics-related details.<\/span><\/p><p><span style=\"font-weight: 400;\">A color gradient (aka color map or a color progression) is a range of position-dependent colors. Usually, it stores colors for some initially known points like \u00abstart\u00bb and \u00abend\u00bb and is used to calculate color values for all other points in-between.<\/span><\/p><p><span style=\"font-weight: 400;\">Depending on the sampling step, the calculation for values in the range [<\/span><span style=\"font-weight: 400;\">0.0; 1.0<\/span><span style=\"font-weight: 400;\">] could be a CPU-consuming task. That is one of the reasons why gradients relatively recently appeared in the regular GUI (remember the Windows Vista with its Aero and the first steps of Compiz in Linux).<\/span><\/p><p><span style=\"font-weight: 400;\">But there is a scope where gradients have been used for ages as more than just bells and whistles.<\/span><\/p><p><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-808e49a elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"808e49a\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5a4d0d9\" data-id=\"5a4d0d9\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3669cab elementor-widget elementor-widget-text-editor\" data-id=\"3669cab\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Gradient charts<\/h2>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-db7f940 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"db7f940\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1b596ce\" data-id=\"1b596ce\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-4d48347 elementor-widget elementor-widget-premium-img-gallery\" data-id=\"4d48347\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;premium_gallery_img_content&quot;:[{&quot;premium_gallery_img_category&quot;:&quot;Category 1&quot;,&quot;_id&quot;:&quot;72209b5&quot;,&quot;premium_gallery_img&quot;:{&quot;url&quot;:&quot;https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Chart1.jpg&quot;,&quot;id&quot;:880,&quot;size&quot;:&quot;&quot;},&quot;premium_gallery_image_cell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_video&quot;:&quot;&quot;,&quot;premium_gallery_video_type&quot;:null,&quot;premium_gallery_video_url&quot;:null,&quot;premium_gallery_video_self&quot;:null,&quot;premium_gallery_video_self_url&quot;:null,&quot;premium_gallery_video_controls&quot;:null,&quot;premium_gallery_video_mute&quot;:null,&quot;premium_gallery_video_loop&quot;:null,&quot;download_button&quot;:null,&quot;privacy_mode&quot;:null,&quot;premmium_gallery_img_info&quot;:&quot;&quot;,&quot;premium_gallery_img_name&quot;:&quot;&quot;,&quot;premium_gallery_img_desc&quot;:&quot;&quot;,&quot;premium_gallery_img_link_type&quot;:&quot;url&quot;,&quot;premium_gallery_img_link&quot;:{&quot;url&quot;:&quot;&quot;,&quot;is_external&quot;:&quot;&quot;,&quot;nofollow&quot;:&quot;&quot;,&quot;custom_attributes&quot;:&quot;&quot;},&quot;premium_gallery_img_existing&quot;:null,&quot;premium_gallery_link_whole&quot;:&quot;&quot;,&quot;premium_gallery_lightbox_whole&quot;:&quot;&quot;},{&quot;premium_gallery_img_category&quot;:&quot;Category 2&quot;,&quot;_id&quot;:&quot;391208b&quot;,&quot;premium_gallery_img&quot;:{&quot;url&quot;:&quot;https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Chart2.jpg&quot;,&quot;id&quot;:881,&quot;size&quot;:&quot;&quot;},&quot;premium_gallery_image_cell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_video&quot;:&quot;&quot;,&quot;premium_gallery_video_type&quot;:null,&quot;premium_gallery_video_url&quot;:null,&quot;premium_gallery_video_self&quot;:null,&quot;premium_gallery_video_self_url&quot;:null,&quot;premium_gallery_video_controls&quot;:null,&quot;premium_gallery_video_mute&quot;:null,&quot;premium_gallery_video_loop&quot;:null,&quot;download_button&quot;:null,&quot;privacy_mode&quot;:null,&quot;premmium_gallery_img_info&quot;:&quot;&quot;,&quot;premium_gallery_img_name&quot;:&quot;&quot;,&quot;premium_gallery_img_desc&quot;:&quot;&quot;,&quot;premium_gallery_img_link_type&quot;:&quot;url&quot;,&quot;premium_gallery_img_link&quot;:{&quot;url&quot;:&quot;&quot;,&quot;is_external&quot;:&quot;&quot;,&quot;nofollow&quot;:&quot;&quot;,&quot;custom_attributes&quot;:&quot;&quot;},&quot;premium_gallery_img_existing&quot;:null,&quot;premium_gallery_link_whole&quot;:&quot;&quot;,&quot;premium_gallery_lightbox_whole&quot;:&quot;&quot;},{&quot;_id&quot;:&quot;bde7fad&quot;,&quot;premium_gallery_img&quot;:{&quot;url&quot;:&quot;https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Chart4.jpg&quot;,&quot;id&quot;:883,&quot;size&quot;:&quot;&quot;},&quot;premium_gallery_image_cell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_video&quot;:&quot;&quot;,&quot;premium_gallery_video_type&quot;:null,&quot;premium_gallery_video_url&quot;:null,&quot;premium_gallery_video_self&quot;:null,&quot;premium_gallery_video_self_url&quot;:null,&quot;premium_gallery_video_controls&quot;:null,&quot;premium_gallery_video_mute&quot;:null,&quot;premium_gallery_video_loop&quot;:null,&quot;download_button&quot;:null,&quot;privacy_mode&quot;:null,&quot;premmium_gallery_img_info&quot;:&quot;&quot;,&quot;premium_gallery_img_name&quot;:&quot;&quot;,&quot;premium_gallery_img_desc&quot;:&quot;&quot;,&quot;premium_gallery_img_category&quot;:&quot;&quot;,&quot;premium_gallery_img_link_type&quot;:&quot;url&quot;,&quot;premium_gallery_img_link&quot;:{&quot;url&quot;:&quot;&quot;,&quot;is_external&quot;:&quot;&quot;,&quot;nofollow&quot;:&quot;&quot;,&quot;custom_attributes&quot;:&quot;&quot;},&quot;premium_gallery_img_existing&quot;:null,&quot;premium_gallery_link_whole&quot;:&quot;&quot;,&quot;premium_gallery_lightbox_whole&quot;:&quot;&quot;},{&quot;_id&quot;:&quot;5c0d673&quot;,&quot;premium_gallery_img&quot;:{&quot;url&quot;:&quot;https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Chart3.jpg&quot;,&quot;id&quot;:882,&quot;size&quot;:&quot;&quot;},&quot;premium_gallery_image_cell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_cell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:4,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_image_vcell_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;premium_gallery_video&quot;:&quot;&quot;,&quot;premium_gallery_video_type&quot;:null,&quot;premium_gallery_video_url&quot;:null,&quot;premium_gallery_video_self&quot;:null,&quot;premium_gallery_video_self_url&quot;:null,&quot;premium_gallery_video_controls&quot;:null,&quot;premium_gallery_video_mute&quot;:null,&quot;premium_gallery_video_loop&quot;:null,&quot;download_button&quot;:null,&quot;privacy_mode&quot;:null,&quot;premmium_gallery_img_info&quot;:&quot;&quot;,&quot;premium_gallery_img_name&quot;:&quot;&quot;,&quot;premium_gallery_img_desc&quot;:&quot;&quot;,&quot;premium_gallery_img_category&quot;:&quot;&quot;,&quot;premium_gallery_img_link_type&quot;:&quot;url&quot;,&quot;premium_gallery_img_link&quot;:{&quot;url&quot;:&quot;&quot;,&quot;is_external&quot;:&quot;&quot;,&quot;nofollow&quot;:&quot;&quot;,&quot;custom_attributes&quot;:&quot;&quot;},&quot;premium_gallery_img_existing&quot;:null,&quot;premium_gallery_link_whole&quot;:&quot;&quot;,&quot;premium_gallery_lightbox_whole&quot;:&quot;&quot;}]}\" data-widget_type=\"premium-img-gallery.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\n\t<div class=\"premium-img-gallery-no-lightbox elementor-invisible premium-img-gallery premium-img-gallery-masonry none\" id=\"premium-img-gallery-4d48347\">\n\t\t\n\t\t<div class=\"premium-gallery-container\" data-settings=\"{&quot;img_size&quot;:&quot;masonry&quot;,&quot;filter&quot;:&quot;&quot;,&quot;theme&quot;:null,&quot;active_cat&quot;:&quot;*&quot;,&quot;ltr_mode&quot;:true,&quot;shuffle&quot;:false,&quot;sort_by&quot;:&quot;original-order&quot;,&quot;skin&quot;:&quot;default&quot;}\">\n\n\t\t\t\t\t\t\t<div class=\"premium-gallery-item elementor-repeater-item-72209b5 category-1\">\n\t\t\t\t<div class=\"pa-gallery-img default\" onclick=\"\">\n\t\t\t\t\t<div class=\"pa-gallery-img-container\">\n\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"864\" height=\"864\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart1.jpg\" class=\"attachment-full size-full wp-image-1964\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart1.jpg 864w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart1-300x300.jpg 300w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart1-150x150.jpg 150w\" sizes=\"(max-width: 864px) 100vw, 864px\" \/>\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-wrapper\">\n\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-inner-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"premium-gallery-item elementor-repeater-item-391208b category-2\">\n\t\t\t\t<div class=\"pa-gallery-img default\" onclick=\"\">\n\t\t\t\t\t<div class=\"pa-gallery-img-container\">\n\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"512\" height=\"226\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart2.jpg\" class=\"attachment-full size-full wp-image-1965\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart2.jpg 512w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart2-300x132.jpg 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/>\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-wrapper\">\n\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-inner-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"premium-gallery-item elementor-repeater-item-bde7fad \">\n\t\t\t\t<div class=\"pa-gallery-img default\" onclick=\"\">\n\t\t\t\t\t<div class=\"pa-gallery-img-container\">\n\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"512\" height=\"451\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart4.jpg\" class=\"attachment-full size-full wp-image-1967\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart4.jpg 512w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart4-300x264.jpg 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/>\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-wrapper\">\n\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-inner-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"premium-gallery-item elementor-repeater-item-5c0d673 \">\n\t\t\t\t<div class=\"pa-gallery-img default\" onclick=\"\">\n\t\t\t\t\t<div class=\"pa-gallery-img-container\">\n\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"288\" height=\"357\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart3-e1623758126505.jpg\" class=\"attachment-full size-full wp-image-1966\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart3-e1623758126505.jpg 288w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Chart3-e1623758126505-242x300.jpg 242w\" sizes=\"(max-width: 288px) 100vw, 288px\" \/>\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-wrapper\">\n\t\t\t\t\t\t\t\t<div class=\"pa-gallery-icons-inner-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\n\t\t\t\t\t<\/div>\n\n\t\t\n\t<\/div>\n\n\t\t\n\t\t\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c40de95 elementor-widget elementor-widget-text-editor\" data-id=\"c40de95\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">I have been involved in developing both data and navigational chart plotters a few times. During these projects I would sometimes get weird tasks, like \u00abimprove\/reflect the chart and its legend, as shown in\u2026\u00bb. This would come with a screenshot in a bug tracker or just a chain of clicks to be performed to get to the related screen in an existing application we didn&#8217;t have sources on.<\/span>\n\n<span style=\"font-weight: 400;\">The first time I got such a task, I was too young and <\/span><span style=\"text-decoration: line-through;\">in need of money<\/span><span style=\"font-weight: 400;\"> active. So I spent some time with a screenshot and the color picker tool\u2026<\/span>\n\n<span style=\"font-weight: 400;\">The next time, I tried to \u00abwork smart, not hard\u00bb and made a tool for single-time use. Or at least I thought it would be single-time use.<\/span><br><br>\n\n<span style=\"font-weight: 400;\">When I got to such a task a third time, I realized two things. First, the previously created tool had been lost to oblivion in the company that I had left years ago. Second, it seems the Karma exists and I&#8217;m doomed to get such malformed tasks. So, let&#8217;s write it again, for hopefully the last time!<\/span>\n\n<span style=\"font-weight: 400;\">To begin with, let\u2019s look at the API available in the<\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9dbbdfd elementor-widget elementor-widget-text-editor\" data-id=\"9dbbdfd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>QLinearGradient:<\/h2>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9d1b0b4 elementor-widget elementor-widget-code-highlight\" data-id=\"9d1b0b4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   \/\/    QLinearGradient();\r\n   \/\/    QLinearGradient(const QPointF &start, const QPointF &finalStop);\r\n   \/\/    QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)\r\n   QLinearGradient lg(10., 10., 110., 110.);\r\n   lg.setColorAt(0.0, Qt::red);\r\n   lg.setColorAt(0.5, Qt::green);\r\n   lg.setColorAt(1.0, Qt::blue);\r\n   QPainter painter(this);\r\n   painter.setBrush(lg);\r\n   painter.drawRect({10, 10, 110, 110});<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7ec46b7 elementor-widget elementor-widget-image\" data-id=\"7ec46b7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"303\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient1.jpg\" class=\"attachment-large size-large wp-image-1955\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient1.jpg 278w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient1-275x300.jpg 275w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f4f95c5 elementor-widget elementor-widget-text-editor\" data-id=\"f4f95c5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Now let\u2019s try to fill an area that is different from the one used to initialize the gradient \u2013\u00a0<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-90c3ad4 elementor-widget elementor-widget-code-highlight\" data-id=\"90c3ad4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>painter.drawRect({10, 10, 210, 210});<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-87a363d elementor-widget elementor-widget-image\" data-id=\"87a363d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"303\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient2.jpg\" class=\"attachment-large size-large wp-image-1956\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient2.jpg 278w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient2-275x300.jpg 275w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-61d2544 elementor-widget elementor-widget-text-editor\" data-id=\"61d2544\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">As shown in the image above, the last color is used to fill the rest of the increased area. By default, a <code>QLinearGradient<\/code><span style=\"font-weight: 400;\"> operates in the Logical Coordinates mode. That means that such a gradient is fixed to the initially set shape and has to be updated manually each time the shape is changed. Considering our goal \u2013 to grab a gradient from a raster image and reuse it in our software \u2013 most probably, being locked in dimensions of the source image is not what we actually want. To make automatically stretchable gradient, we have to specify its coordinates in a different scope, bounded to the range of [<code>0.0; 1.0<\/code>] in both axes:<\/span><\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c62727e elementor-widget elementor-widget-code-highlight\" data-id=\"c62727e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   QLinearGradient lg;\r\n   lg.setStart(0., 0.);     \/\/ top left\r\n   lg.setFinalStop(1., 1.); \/\/ bottom right\r\n   lg.setCoordinateMode(QGradient::ObjectMode); \/\/ maps the points to a painter coordinates\r\n   \u2026\r\n   painter.drawRect({10, 10, 210, 210});<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7317fec elementor-widget elementor-widget-image\" data-id=\"7317fec\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"303\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient3.jpg\" class=\"attachment-large size-large wp-image-1957\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient3.jpg 278w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient3-275x300.jpg 275w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0089267 elementor-widget elementor-widget-text-editor\" data-id=\"0089267\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">To reverse the gradient flow direction, one may either swap its <\/span><code>start<\/code><span style=\"font-weight: 400;\"> and <\/span><code>finalStop<\/code><span style=\"font-weight: 400;\"> points:<\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-28d7912 elementor-widget elementor-widget-code-highlight\" data-id=\"28d7912\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   lg.setStart(1., 1.);     \/\/ bottom right\r\n   lg.setFinalStop(0., 0.); \/\/ top left\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5f0301e elementor-widget elementor-widget-image\" data-id=\"5f0301e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"303\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient4.jpg\" class=\"attachment-large size-large wp-image-1958\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient4.jpg 278w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinearGradient4-275x300.jpg 275w\" sizes=\"(max-width: 278px) 100vw, 278px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d707b63 elementor-widget elementor-widget-text-editor\" data-id=\"d707b63\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">or change the color point coordinates accordingly:<\/span><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f2701bf elementor-widget elementor-widget-code-highlight\" data-id=\"f2701bf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>\r\n\r\n   \/\/ original\r\n   lg.setColorAt(0.0, Qt::red);\r\n   lg.setColorAt(0.5, Qt::green);\r\n   lg.setColorAt(1.0, Qt::blue);\r\n\r\n   \/\/ reversed\r\n   lg.setColorAt(1.0, Qt::red);\r\n   lg.setColorAt(0.5, Qt::green);\r\n   lg.setColorAt(0.0, Qt::blue);\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-214888f elementor-widget elementor-widget-text-editor\" data-id=\"214888f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Now we know enough to grab a gradient from a raster image. The idea is quite simple: scan the lines of the image pixel by pixel and map its color to a point in the gradient.<\/span><\/p><p><span style=\"font-weight: 400;\">As we have seen, a color is assigned to some abstract position in the range [<\/span><code>0.0; 1.0<\/code><span style=\"font-weight: 400;\">]. Obviously, the mapping of a pixel (integer coordinates) to such position and back involves floating-point calculations, which leads to the rounding problem and a loss of some information. Because of this, even grabbing a gradient locally rendered by Qt and rendering it in the same coordinates would not get us an absolute copy of the original image. Things may get even worse if a source gradient image was rendered on a different platform.<\/span><\/p><p><span style=\"font-weight: 400;\">But usually, the \u00abred\u00bb is \u00abred\u00bb for the<\/span><span style=\"font-weight: 400;\"> human eye, and it doesn&#8217;t matter if it&#8217;s specified as (<\/span><code>247, 0, 0<\/code>) or (<code>253, 0, 0<\/code><span style=\"font-weight: 400;\">):<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-636b992 elementor-widget elementor-widget-gallery\" data-id=\"636b992\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;gallery_layout&quot;:&quot;masonry&quot;,&quot;columns&quot;:2,&quot;gap&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:100,&quot;sizes&quot;:[]},&quot;columns_tablet&quot;:2,&quot;columns_mobile&quot;:1,&quot;gap_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:10,&quot;sizes&quot;:[]},&quot;gap_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:10,&quot;sizes&quot;:[]},&quot;link_to&quot;:&quot;file&quot;,&quot;overlay_background&quot;:&quot;yes&quot;,&quot;content_hover_animation&quot;:&quot;fade-in&quot;}\" data-widget_type=\"gallery.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-gallery__container\">\n\t\t\t\t\t\t\t<a class=\"e-gallery-item elementor-gallery-item elementor-animated-content\" href=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/RedisRed.jpg\" data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"636b992\" data-elementor-lightbox-title=\"RedisRed\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6ODc2LCJ1cmwiOiJodHRwczpcL1wvd3d3LnZpa2luZ3NvZnR3YXJlLmNvbVwvd3AtY29udGVudFwvdXBsb2Fkc1wvMjAyMVwvMDZcL1JlZGlzUmVkLmpwZyIsInNsaWRlc2hvdyI6IjYzNmI5OTIifQ%3D%3D\">\n\t\t\t\t\t<div class=\"e-gallery-image elementor-gallery-item__image\" data-thumbnail=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/RedisRed.jpg\" data-width=\"278\" data-height=\"303\" aria-label=\"Red is Red\" role=\"img\" ><\/div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-gallery-item__overlay\"><\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t<a class=\"e-gallery-item elementor-gallery-item elementor-animated-content\" href=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/ColorScale.jpg\" data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"636b992\" data-elementor-lightbox-title=\"ColorScale\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6ODg0LCJ1cmwiOiJodHRwczpcL1wvd3d3LnZpa2luZ3NvZnR3YXJlLmNvbVwvd3AtY29udGVudFwvdXBsb2Fkc1wvMjAyMVwvMDZcL0NvbG9yU2NhbGUuanBnIiwic2xpZGVzaG93IjoiNjM2Yjk5MiJ9\">\n\t\t\t\t\t<div class=\"e-gallery-image elementor-gallery-item__image\" data-thumbnail=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/ColorScale.jpg\" data-width=\"512\" data-height=\"512\" aria-label=\"Color scale\" role=\"img\" ><\/div>\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-gallery-item__overlay\"><\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-96bb6c0 elementor-widget elementor-widget-text-editor\" data-id=\"96bb6c0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">And that is acceptable since we need a gradient for a chart or its legend. In other words, the data mapped to a point &#8220;red&#8221; (<code>253, 0, 0<\/code><span style=\"font-weight: 400;\">) should always be displayed as (<\/span><code>253, 0, 0<\/code><span style=\"font-weight: 400;\">), and the fact it was the (<\/span><code>247, 0, 0<\/code><span style=\"font-weight: 400;\">) in the original image does not matter. And this is exactly what we are about to achieve. So\u2026<\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-2752f29 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"2752f29\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-0336656\" data-id=\"0336656\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-07f3f4a elementor-widget elementor-widget-text-editor\" data-id=\"07f3f4a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Let\u2019s code a bit<\/h2>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5730bc0 elementor-widget elementor-widget-text-editor\" data-id=\"5730bc0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">The only available input data we have is an image to be scanned, a line that describes the direction of the scan in the pixel coordinates, and the count of steps to be performed \u2013 the desired density of the resulting gradient:<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4ed72bc elementor-widget elementor-widget-code-highlight\" data-id=\"4ed72bc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>QString grabGradientFromImage(const QImage *image, const QLine &pixelsLine, int steps) {\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fe9b63f elementor-widget elementor-widget-text-editor\" data-id=\"fe9b63f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">First of all, let\u2019s prepare helpers based on the input. There will be a lot of work with <\/span><code>qreal<\/code><span style=\"font-weight: 400;\"> data, so it is a good idea to wrap the <\/span><code>pixelsLine<\/code><span style=\"font-weight: 400;\"> into a <\/span><code>QLineF<\/code><span style=\"font-weight: 400;\">.<\/span><\/p><p><span style=\"font-weight: 400;\">To iterate pixels, we have to know the size of the single shift. It based on the total length of the pixels line, its unit vector, and the desired steps count:<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2774b03 elementor-widget elementor-widget-code-highlight\" data-id=\"2774b03\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   const QLineF lineF(pixelsLine);\r\n   const QLineF unitVector = lineF.translated(-lineF.p1()).unitVector();\r\n   const QPointF shift = unitVector.p2() * (lineF.length() \/ qreal(steps));<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-264675c elementor-widget elementor-widget-text-editor\" data-id=\"264675c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">Instead of manual mapping of a pixel position to the range [<\/span><code>0.0; 1.0<\/code>], <span style=\"font-weight: 400;\">I\u2019d prefer to use the existing API of <\/span><code>QPainterPath:<\/code>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8cea225 elementor-widget elementor-widget-code-highlight\" data-id=\"8cea225\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   const QPainterPath linePath([](const QLineF &line) -> QPainterPath {\r\n       QPainterPath path;\r\n       path.moveTo(line.p1());\r\n       path.lineTo(line.p2());\r\n       return path;\r\n   }(lineF));<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3c16771 elementor-widget elementor-widget-text-editor\" data-id=\"3c16771\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Since the original image rectangle is also in use, it worth to keep a const ref to it to avoid unnecessary calls within a loop:<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1fb7f40 elementor-widget elementor-widget-code-highlight\" data-id=\"1fb7f40\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   const QRect imgRect = image->rect();\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7dc6d0e elementor-widget elementor-widget-text-editor\" data-id=\"7dc6d0e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Now it\u2019s the turn for the rest of the workers. There is just a couple of non-consts: a line that actually is a vector directed to the current pixel, and a collection of gradient stops to store the collected data:<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9b8f240 elementor-widget elementor-widget-code-highlight\" data-id=\"9b8f240\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   QLineF progressLine(lineF.p1(), lineF.p1());\r\n   QGradientStops gradientStops;<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de430fc elementor-widget elementor-widget-text-editor\" data-id=\"de430fc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">When the full <\/span><code>pixelsLine<\/code><span style=\"font-weight: 400;\"> hasn&#8217;t yet been processed, the main working loop checks if the current pixel is still within the image\u2019s rectangle. Then it maps coordinates to the gradient scope and puts the color into the collection of gradient stops:<\/span><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5d13fff elementor-widget elementor-widget-code-highlight\" data-id=\"5d13fff\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   while (progressLine.length() <= lineF.length()) {\r\n       if (imgRect.contains(progressLine.p2().toPoint())) {\r\n           const QColor color = image->pixelColor(progressLine.p2().toPoint());\r\n           const qreal posInGradient = linePath.percentAtLength(progressLine.length());\r\n           gradientStops.append({ posInGradient, color });\r\n       }\r\n       progressLine.setP2(progressLine.p2() + shift);\r\n   }\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-544b0ec elementor-widget elementor-widget-text-editor\" data-id=\"544b0ec\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">After that we just have to calculate appropriate values for gradient\u2019s <\/span><code>start<\/code><span style=\"font-weight: 400;\"> and <\/span><code>finalStop<\/code><span style=\"font-weight: 400;\"> points and generate the text:<\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-21517f0 elementor-widget elementor-widget-code-highlight\" data-id=\"21517f0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>   QPointF start(lineF.p1()), stop(lineF.p2());\r\n   QPointF limit(imgRect.bottomRight());\r\n   for (QPointF *pnt : { &start, &stop }) {\r\n       pnt->rx() = pnt->x() \/ limit.x();\r\n       pnt->ry() = pnt->y() \/ limit.y();\r\n   }\r\n   if (unitVector.p2().x() < 0 || unitVector.p2().y() < 0)\r\n       qSwap(start, stop);\r\n\r\n   return prepareText(gradientStops, start, stop);\r\n}\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9a73a7a elementor-widget elementor-widget-text-editor\" data-id=\"9a73a7a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<span style=\"font-weight: 400;\">Obviously, the <\/span><code>prepareText<\/code><span style=\"font-weight: 400;\"> function is something like: <\/span>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a8e004c elementor-widget elementor-widget-code-highlight\" data-id=\"a8e004c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>QString prepareText( const QGradientStops& stops, const QPointF& start, const QPointF& end) {\u2026};<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6db1c12 elementor-widget elementor-widget-text-editor\" data-id=\"6db1c12\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">but it is too trivial and out of the scope of our discussion.\u00a0<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-23f19be elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"23f19be\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1074ebe\" data-id=\"1074ebe\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3904ca3 elementor-widget elementor-widget-text-editor\" data-id=\"3904ca3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>Complete code<\/h2>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-14edcc3 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"14edcc3\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-33b8a43\" data-id=\"33b8a43\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-b3424f2 elementor-widget elementor-widget-text-editor\" data-id=\"b3424f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">Although the function described here is compilable, it is more a pseudocode. Here is its complete body for those who looked for a quick solution to copy-n-paste and tune it:<\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ea8ca61 elementor-widget elementor-widget-code-highlight\" data-id=\"ea8ca61\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-tomorrow copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>QString grabGradientFromImage(const QImage *image, const QLine &pixelsLine, int steps)\r\n{\r\n   const QLineF lineF(pixelsLine);\r\n   const QLineF unitVector = lineF.translated(-lineF.p1()).unitVector();\r\n   const QPointF shift = unitVector.p2() * (lineF.length() \/ qreal(steps));\r\n\r\n   const QPainterPath linePath([](const QLineF &line) -> QPainterPath {\r\n       QPainterPath path;\r\n       path.moveTo(line.p1());\r\n       path.lineTo(line.p2());\r\n       return path;\r\n   }(lineF));\r\n\r\n   const QRect imgRect = image->rect();\r\n\r\n   QLineF progressLine(lineF.p1(), lineF.p1());\r\n   QGradientStops gradientStops;\r\n\r\n   while (progressLine.length() <= lineF.length()) {\r\n       if (imgRect.contains(progressLine.p2().toPoint())) {\r\n           const QColor color = image->pixelColor(progressLine.p2().toPoint());\r\n           const qreal posInGradient = linePath.percentAtLength(progressLine.length());\r\n           gradientStops.append({ posInGradient, color });\r\n       }\r\n       progressLine.setP2(progressLine.p2() + shift);\r\n   }\r\n\r\n   QPointF start(lineF.p1()), stop(lineF.p2());\r\n   QPointF limit(imgRect.bottomRight());\r\n   for (QPointF *pnt : { &start, &stop }) {\r\n       pnt->rx() = pnt->x() \/ limit.x();\r\n       pnt->ry() = pnt->y() \/ limit.y();\r\n   }\r\n   if (unitVector.p2().x() < 0. || unitVector.p2().y() < 0.)\r\n       qSwap(start, stop);\r\n\r\n   return prepareText(gradientStops, start, stop);\r\n}\r\n<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-412b78f elementor-widget elementor-widget-text-editor\" data-id=\"412b78f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"font-weight: 400;\">You can find the complete source code, split in a static library and a GUI application with fancy bells and whistles, here: <a href=\"https:\/\/gitlab.com\/vikingsoftware\/qlingradgen\">https:\/\/gitlab.com\/vikingsoftware\/qlingradgen<\/a><\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-39ac972 elementor-widget elementor-widget-image\" data-id=\"39ac972\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"904\" height=\"648\" src=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinGradGen_h.png\" class=\"attachment-large size-large wp-image-1950\" alt=\"\" srcset=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinGradGen_h.png 904w, https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/QLinGradGen_h-300x215.png 300w\" sizes=\"(max-width: 904px) 100vw, 904px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-6f1c31b elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"6f1c31b\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-144d69b\" data-id=\"144d69b\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-e3657f3 elementor-widget elementor-widget-text-editor\" data-id=\"e3657f3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>So there you have it. Hopefully you find my tool useful, and won&#8217;t have issues with weird tasks like I did.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section data-particle_enable=\"false\" data-particle-mobile-disabled=\"false\" class=\"elementor-section elementor-top-section elementor-element elementor-element-d7f6c5c elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"d7f6c5c\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1e0234f\" data-id=\"1e0234f\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>The the description and code behind a tool that helps generating the gradient C++ code out of a raster image.<\/p>\n","protected":false},"author":4,"featured_media":1951,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[94],"tags":[96,98,95,99],"class_list":["post-2589","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-da","tag-cplusplus-da","tag-desktop-da","tag-qt-da","tag-widgets-da"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>QLinearGradient strikes back - Viking Software A\/S<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/\" \/>\n<meta property=\"og:locale\" content=\"da_DK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"QLinearGradient strikes back - Viking Software A\/S\" \/>\n<meta property=\"og:description\" content=\"The the description and code behind a tool that helps generating the gradient C++ code out of a raster image.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/\" \/>\n<meta property=\"og:site_name\" content=\"Viking Software A\/S\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-10T11:40:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-1.jpg\" \/>\n<meta name=\"author\" content=\"Maria Lisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Skrevet af\" \/>\n\t<meta name=\"twitter:data1\" content=\"Maria Lisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimeret l\u00e6setid\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/\"},\"author\":{\"name\":\"Maria Lisberg\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/#\\\/schema\\\/person\\\/9b67e226302628047186fd9359931e56\"},\"headline\":\"QLinearGradient strikes back\",\"datePublished\":\"2021-06-10T11:40:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/\"},\"wordCount\":1207,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Gradients.png\",\"keywords\":[\"C++\",\"Desktop\",\"Qt\",\"Widgets\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/\",\"url\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/\",\"name\":\"QLinearGradient strikes back - Viking Software A\\\/S\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Gradients.png\",\"datePublished\":\"2021-06-10T11:40:41+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/#\\\/schema\\\/person\\\/9b67e226302628047186fd9359931e56\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#breadcrumb\"},\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Gradients.png\",\"contentUrl\":\"https:\\\/\\\/www.vikingsoftware.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Gradients.png\",\"width\":1400,\"height\":600},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/blog-da\\\/qlinear-gradient-strikes-back\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"QLinearGradient strikes back\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/#website\",\"url\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/\",\"name\":\"Viking Software A\\\/S\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"da-DK\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.vikingsoftware.com\\\/da\\\/#\\\/schema\\\/person\\\/9b67e226302628047186fd9359931e56\",\"name\":\"Maria Lisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g\",\"caption\":\"Maria Lisberg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"QLinearGradient strikes back - Viking Software A\/S","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/","og_locale":"da_DK","og_type":"article","og_title":"QLinearGradient strikes back - Viking Software A\/S","og_description":"The the description and code behind a tool that helps generating the gradient C++ code out of a raster image.","og_url":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/","og_site_name":"Viking Software A\/S","article_published_time":"2021-06-10T11:40:41+00:00","og_image":[{"url":"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/3pics-1.jpg","type":"","width":"","height":""}],"author":"Maria Lisberg","twitter_card":"summary_large_image","twitter_misc":{"Skrevet af":"Maria Lisberg","Estimeret l\u00e6setid":"8 minutter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#article","isPartOf":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/"},"author":{"name":"Maria Lisberg","@id":"https:\/\/www.vikingsoftware.com\/da\/#\/schema\/person\/9b67e226302628047186fd9359931e56"},"headline":"QLinearGradient strikes back","datePublished":"2021-06-10T11:40:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/"},"wordCount":1207,"commentCount":0,"image":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#primaryimage"},"thumbnailUrl":"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Gradients.png","keywords":["C++","Desktop","Qt","Widgets"],"articleSection":["Blog"],"inLanguage":"da-DK","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/","url":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/","name":"QLinearGradient strikes back - Viking Software A\/S","isPartOf":{"@id":"https:\/\/www.vikingsoftware.com\/da\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#primaryimage"},"image":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#primaryimage"},"thumbnailUrl":"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Gradients.png","datePublished":"2021-06-10T11:40:41+00:00","author":{"@id":"https:\/\/www.vikingsoftware.com\/da\/#\/schema\/person\/9b67e226302628047186fd9359931e56"},"breadcrumb":{"@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#breadcrumb"},"inLanguage":"da-DK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/"]}]},{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#primaryimage","url":"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Gradients.png","contentUrl":"https:\/\/www.vikingsoftware.com\/wp-content\/uploads\/2021\/06\/Gradients.png","width":1400,"height":600},{"@type":"BreadcrumbList","@id":"https:\/\/www.vikingsoftware.com\/da\/blog-da\/qlinear-gradient-strikes-back\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.vikingsoftware.com\/da\/"},{"@type":"ListItem","position":2,"name":"QLinearGradient strikes back"}]},{"@type":"WebSite","@id":"https:\/\/www.vikingsoftware.com\/da\/#website","url":"https:\/\/www.vikingsoftware.com\/da\/","name":"Viking Software A\/S","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.vikingsoftware.com\/da\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"da-DK"},{"@type":"Person","@id":"https:\/\/www.vikingsoftware.com\/da\/#\/schema\/person\/9b67e226302628047186fd9359931e56","name":"Maria Lisberg","image":{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/secure.gravatar.com\/avatar\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8b13978f2a67726c7f50acfc73600aa7902481eec9fb6673919cfaf3db353b8?s=96&d=mm&r=g","caption":"Maria Lisberg"}}]}},"_links":{"self":[{"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/posts\/2589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/comments?post=2589"}],"version-history":[{"count":0,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/posts\/2589\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/media\/1951"}],"wp:attachment":[{"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/media?parent=2589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/categories?post=2589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.vikingsoftware.com\/da\/wp-json\/wp\/v2\/tags?post=2589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}