// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/utility/cropping_util.h"
#include <ostream>
#include "base/check.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/skia_conversions.h"
namespace ash {
SkBitmap CenterCropImage(const SkBitmap& image, const gfx::Size& target_size) {
DCHECK(!image.empty());
DCHECK(!image.isNull());
DCHECK(!target_size.IsEmpty());
const int orig_width = image.width();
const int orig_height = image.height();
const int new_width = target_size.width();
const int new_height = target_size.height();
// The dimension with the smallest ratio must be cropped, the other
// one is preserved. Both are set in gfx::Size cropped_size.
double horizontal_ratio =
static_cast<double>(new_width) / static_cast<double>(orig_width);
double vertical_ratio =
static_cast<double>(new_height) / static_cast<double>(orig_height);
gfx::Size cropped_size;
if (vertical_ratio > horizontal_ratio) {
cropped_size =
gfx::Size(base::ClampRound(new_width / vertical_ratio), orig_height);
DCHECK_LE(cropped_size.width(), orig_width);
} else {
cropped_size =
gfx::Size(orig_width, base::ClampRound(new_height / horizontal_ratio));
DCHECK_LE(cropped_size.height(), orig_height);
}
gfx::Rect cropped_rect(orig_width, orig_height);
cropped_rect.ClampToCenteredSize(cropped_size);
SkBitmap sub_image;
if (!image.extractSubset(&sub_image, gfx::RectToSkIRect(cropped_rect))) {
NOTREACHED() << "Cropping image with dimensions "
<< gfx::Size(orig_width, orig_height).ToString() << " to "
<< cropped_rect.ToString() << " failed.";
}
return sub_image;
}
} // namespace ash