Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: chrome/browser/thumbnails/content_based_thumbnailing_algorithm.cc

Issue 1348833003: Fix NTP thumbnail generation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nit. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/thumbnails/content_based_thumbnailing_algorithm.h" 5 #include "chrome/browser/thumbnails/content_based_thumbnailing_algorithm.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/threading/sequenced_worker_pool.h" 8 #include "base/threading/sequenced_worker_pool.h"
9 #include "chrome/browser/thumbnails/content_analysis.h" 9 #include "chrome/browser/thumbnails/content_analysis.h"
10 #include "chrome/browser/thumbnails/simple_thumbnail_crop.h" 10 #include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 SimpleThumbnailCrop::ComputeTargetSizeAtMaximumScale(target_size_); 69 SimpleThumbnailCrop::ComputeTargetSizeAtMaximumScale(target_size_);
70 70
71 SkBitmap source_bitmap = 71 SkBitmap source_bitmap =
72 PrepareSourceBitmap(bitmap, target_thumbnail_size, context.get()); 72 PrepareSourceBitmap(bitmap, target_thumbnail_size, context.get());
73 73
74 // If the source is same (or smaller) than the target, just return it as 74 // If the source is same (or smaller) than the target, just return it as
75 // the final result. Otherwise, send the shrinking task to the blocking 75 // the final result. Otherwise, send the shrinking task to the blocking
76 // thread pool. 76 // thread pool.
77 if (source_bitmap.width() <= target_thumbnail_size.width() || 77 if (source_bitmap.width() <= target_thumbnail_size.width() ||
78 source_bitmap.height() <= target_thumbnail_size.height()) { 78 source_bitmap.height() <= target_thumbnail_size.height()) {
79 context->score.boring_score = 79 context->SetBoringScore(color_utils::CalculateBoringScore(source_bitmap));
80 color_utils::CalculateBoringScore(source_bitmap); 80 ClipResult clip_result = context->clip_result();
81 context->score.good_clipping = 81 bool good_clipping =
82 (context->clip_result == CLIP_RESULT_WIDER_THAN_TALL || 82 (clip_result == CLIP_RESULT_WIDER_THAN_TALL ||
83 context->clip_result == CLIP_RESULT_TALLER_THAN_WIDE || 83 clip_result == CLIP_RESULT_TALLER_THAN_WIDE ||
84 context->clip_result == CLIP_RESULT_NOT_CLIPPED || 84 clip_result == CLIP_RESULT_NOT_CLIPPED ||
85 context->clip_result == CLIP_RESULT_SOURCE_SAME_AS_TARGET); 85 clip_result == CLIP_RESULT_SOURCE_SAME_AS_TARGET);
86 context->SetGoodClipping(good_clipping);
86 87
87 callback.Run(*context.get(), source_bitmap); 88 callback.Run(*context.get(), source_bitmap);
88 return; 89 return;
89 } 90 }
90 91
91 if (!BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( 92 if (!BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
92 FROM_HERE, 93 FROM_HERE,
93 base::Bind(&CreateRetargetedThumbnail, 94 base::Bind(&CreateRetargetedThumbnail,
94 source_bitmap, 95 source_bitmap,
95 target_thumbnail_size, 96 target_thumbnail_size,
96 context, 97 context,
97 callback), 98 callback),
98 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)) { 99 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)) {
99 LOG(WARNING) << "PostSequencedWorkerTask failed. The thumbnail for " 100 LOG(WARNING) << "PostSequencedWorkerTask failed. The thumbnail will "
100 << context->url << " will not be created."; 101 << "will not be created.";
102 if (context->web_contents() != nullptr) {
103 LOG(WARNING) << "The URL was " << context->GetURL() << ".";
104 } else {
105 LOG(WARNING) << "No URL was specified.";
106 }
101 } 107 }
102 } 108 }
103 109
104 // static 110 // static
105 SkBitmap ContentBasedThumbnailingAlgorithm::PrepareSourceBitmap( 111 SkBitmap ContentBasedThumbnailingAlgorithm::PrepareSourceBitmap(
106 const SkBitmap& received_bitmap, 112 const SkBitmap& received_bitmap,
107 const gfx::Size& thumbnail_size, 113 const gfx::Size& thumbnail_size,
108 ThumbnailingContext* context) { 114 ThumbnailingContext* context) {
109 gfx::Size resize_target; 115 gfx::Size resize_target;
110 SkBitmap clipped_bitmap; 116 SkBitmap clipped_bitmap;
111 if (context->clip_result == CLIP_RESULT_UNPROCESSED) { 117 if (context->clip_result() == CLIP_RESULT_UNPROCESSED) {
112 // This case will require extracting a fragment from the retrieved bitmap. 118 // This case will require extracting a fragment from the retrieved bitmap.
113 int scrollbar_size = gfx::scrollbar_size(); 119 int scrollbar_size = gfx::scrollbar_size();
114 gfx::Size scrollbarless( 120 gfx::Size scrollbarless(
115 std::max(1, received_bitmap.width() - scrollbar_size), 121 std::max(1, received_bitmap.width() - scrollbar_size),
116 std::max(1, received_bitmap.height() - scrollbar_size)); 122 std::max(1, received_bitmap.height() - scrollbar_size));
117 123
124 ClipResult clip_result;
118 gfx::Rect clipping_rect = GetClippingRect( 125 gfx::Rect clipping_rect = GetClippingRect(
119 scrollbarless, 126 scrollbarless,
120 thumbnail_size, 127 thumbnail_size,
121 &resize_target, 128 &resize_target,
122 &context->clip_result); 129 &clip_result);
130 context->set_clip_result(clip_result);
123 131
124 received_bitmap.extractSubset(&clipped_bitmap, 132 received_bitmap.extractSubset(&clipped_bitmap,
125 gfx::RectToSkIRect(clipping_rect)); 133 gfx::RectToSkIRect(clipping_rect));
126 } else { 134 } else {
127 // This means that the source bitmap has been requested and at least 135 // This means that the source bitmap has been requested and at least
128 // clipped. Upstream code in same cases seems opportunistic and it may 136 // clipped. Upstream code in same cases seems opportunistic and it may
129 // not perform actual resizing if copying with resize is not supported. 137 // not perform actual resizing if copying with resize is not supported.
130 // In this case we will resize to the orignally requested copy size. 138 // In this case we will resize to the orignally requested copy size.
131 resize_target = context->requested_copy_size; 139 resize_target = context->requested_copy_size();
132 clipped_bitmap = received_bitmap; 140 clipped_bitmap = received_bitmap;
133 } 141 }
134 142
135 SkBitmap result_bitmap = SkBitmapOperations::DownsampleByTwoUntilSize( 143 SkBitmap result_bitmap = SkBitmapOperations::DownsampleByTwoUntilSize(
136 clipped_bitmap, resize_target.width(), resize_target.height()); 144 clipped_bitmap, resize_target.width(), resize_target.height());
137 #if !defined(USE_AURA) 145 #if !defined(USE_AURA)
138 // If the bitmap has not been indeed resized, it has to be copied. In that 146 // If the bitmap has not been indeed resized, it has to be copied. In that
139 // case resampler simply returns a reference to the original bitmap, sitting 147 // case resampler simply returns a reference to the original bitmap, sitting
140 // in PlatformCanvas. One does not simply assign these 'magic' bitmaps to 148 // in PlatformCanvas. One does not simply assign these 'magic' bitmaps to
141 // SkBitmap. They cannot be refcounted. 149 // SkBitmap. They cannot be refcounted.
(...skipping 10 matching lines...) Expand all
152 } 160 }
153 161
154 // static 162 // static
155 void ContentBasedThumbnailingAlgorithm::CreateRetargetedThumbnail( 163 void ContentBasedThumbnailingAlgorithm::CreateRetargetedThumbnail(
156 const SkBitmap& source_bitmap, 164 const SkBitmap& source_bitmap,
157 const gfx::Size& thumbnail_size, 165 const gfx::Size& thumbnail_size,
158 scoped_refptr<ThumbnailingContext> context, 166 scoped_refptr<ThumbnailingContext> context,
159 const ConsumerCallback& callback) { 167 const ConsumerCallback& callback) {
160 base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now(); 168 base::TimeTicks begin_compute_thumbnail = base::TimeTicks::Now();
161 float kernel_sigma = 169 float kernel_sigma =
162 context->clip_result == CLIP_RESULT_SOURCE_SAME_AS_TARGET ? 5.0f : 2.5f; 170 context->clip_result() == CLIP_RESULT_SOURCE_SAME_AS_TARGET ? 5.0f : 2.5f;
163 SkBitmap thumbnail = thumbnailing_utils::CreateRetargetedThumbnailImage( 171 SkBitmap thumbnail = thumbnailing_utils::CreateRetargetedThumbnailImage(
164 source_bitmap, thumbnail_size, kernel_sigma); 172 source_bitmap, thumbnail_size, kernel_sigma);
165 bool processing_failed = thumbnail.empty(); 173 bool processing_failed = thumbnail.empty();
166 if (processing_failed) { 174 if (processing_failed) {
167 // Log and apply the method very much like in SimpleThumbnailCrop (except 175 // Log and apply the method very much like in SimpleThumbnailCrop (except
168 // that some clipping and copying is not required). 176 // that some clipping and copying is not required).
169 LOG(WARNING) << "CreateRetargetedThumbnailImage failed. " 177 LOG(WARNING) << "CreateRetargetedThumbnailImage failed. "
170 << "The thumbnail for " << context->url 178 << "Creating the thumbnail the old-fashioned way.";
171 << " will be created the old-fashioned way."; 179 if (context->web_contents()) {
180 LOG(WARNING) << "The URL was " << context->GetURL();
181 } else {
182 LOG(WARNING) << "No URL was specified.";
183 }
172 184
173 ClipResult clip_result; 185 ClipResult clip_result;
174 gfx::Rect clipping_rect = SimpleThumbnailCrop::GetClippingRect( 186 gfx::Rect clipping_rect = SimpleThumbnailCrop::GetClippingRect(
175 gfx::Size(source_bitmap.width(), source_bitmap.height()), 187 gfx::Size(source_bitmap.width(), source_bitmap.height()),
176 thumbnail_size, 188 thumbnail_size,
177 &clip_result); 189 &clip_result);
178 source_bitmap.extractSubset(&thumbnail, gfx::RectToSkIRect(clipping_rect)); 190 source_bitmap.extractSubset(&thumbnail, gfx::RectToSkIRect(clipping_rect));
179 thumbnail = SkBitmapOperations::DownsampleByTwoUntilSize( 191 thumbnail = SkBitmapOperations::DownsampleByTwoUntilSize(
180 thumbnail, thumbnail_size.width(), thumbnail_size.height()); 192 thumbnail, thumbnail_size.width(), thumbnail_size.height());
181 } 193 }
182 194
183 if (processing_failed) { 195 if (processing_failed) {
184 LOCAL_HISTOGRAM_TIMES(kFailureHistogramName, 196 LOCAL_HISTOGRAM_TIMES(kFailureHistogramName,
185 base::TimeTicks::Now() - begin_compute_thumbnail); 197 base::TimeTicks::Now() - begin_compute_thumbnail);
186 } else { 198 } else {
187 LOCAL_HISTOGRAM_TIMES(kThumbnailHistogramName, 199 LOCAL_HISTOGRAM_TIMES(kThumbnailHistogramName,
188 base::TimeTicks::Now() - begin_compute_thumbnail); 200 base::TimeTicks::Now() - begin_compute_thumbnail);
189 } 201 }
190 context->score.boring_score = 202 double boring_score = color_utils::CalculateBoringScore(source_bitmap);
191 color_utils::CalculateBoringScore(source_bitmap); 203 if (!processing_failed) {
192 if (!processing_failed) 204 boring_score *= kScoreBoostFromSuccessfulRetargeting;
193 context->score.boring_score *= kScoreBoostFromSuccessfulRetargeting; 205 }
194 context->score.good_clipping = 206 context->SetBoringScore(boring_score);
195 (context->clip_result == CLIP_RESULT_WIDER_THAN_TALL || 207 ClipResult clip_result = context->clip_result();
196 context->clip_result == CLIP_RESULT_TALLER_THAN_WIDE || 208 bool good_clipping =
197 context->clip_result == CLIP_RESULT_NOT_CLIPPED || 209 (clip_result == CLIP_RESULT_WIDER_THAN_TALL ||
198 context->clip_result == CLIP_RESULT_SOURCE_SAME_AS_TARGET); 210 clip_result == CLIP_RESULT_TALLER_THAN_WIDE ||
211 clip_result == CLIP_RESULT_NOT_CLIPPED ||
212 clip_result == CLIP_RESULT_SOURCE_SAME_AS_TARGET);
213 context->SetGoodClipping(good_clipping);
199 // Post the result (the bitmap) back to the callback. 214 // Post the result (the bitmap) back to the callback.
200 BrowserThread::PostTask( 215 BrowserThread::PostTask(
201 BrowserThread::UI, 216 BrowserThread::UI,
202 FROM_HERE, 217 FROM_HERE,
203 base::Bind(&CallbackInvocationAdapter, callback, context, thumbnail)); 218 base::Bind(&CallbackInvocationAdapter, callback, context, thumbnail));
204 } 219 }
205 220
206 ContentBasedThumbnailingAlgorithm::~ContentBasedThumbnailingAlgorithm() { 221 ContentBasedThumbnailingAlgorithm::~ContentBasedThumbnailingAlgorithm() {
207 } 222 }
208 223
(...skipping 24 matching lines...) Expand all
233 } else { 248 } else {
234 clipping_rect = gfx::Rect(source_size); 249 clipping_rect = gfx::Rect(source_size);
235 target_size->SetSize(source_size.width() / 2, source_size.height() / 2); 250 target_size->SetSize(source_size.width() / 2, source_size.height() / 2);
236 *clip_result = CLIP_RESULT_NOT_CLIPPED; 251 *clip_result = CLIP_RESULT_NOT_CLIPPED;
237 } 252 }
238 253
239 return clipping_rect; 254 return clipping_rect;
240 } 255 }
241 256
242 } // namespace thumbnails 257 } // namespace thumbnails
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698