#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>
#include <android/bitmap.h>
#include <android/log.h>
using namespace cv;
#define LOG_TAG "AndroidScalingalgorithmforimage"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
jobject createBitmap(JNIEnv *env, int new_width, int new_height);
extern "C" JNIEXPORT jstring JNICALL
Java_com_kpa_image_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
/**
* 创建目标位图
* @param env
* @param new_width 目标位图 宽
* @param new_height 高
* @return 目标位图
*/
jobject createBitmap(JNIEnv *env, int new_width, int new_height) {
jobject outputBitmap;
jclass bitmapCls = env->FindClass("android/graphics/Bitmap");
jmethodID createBitmapMethod = env->GetStaticMethodID(bitmapCls, "createBitmap",
"(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jstring configName = env->NewStringUTF("ARGB_8888");
jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config");
jobject java_bitmap_config = env->CallStaticObjectMethod(bitmapConfigClass,
env->GetStaticMethodID(
bitmapConfigClass, "valueOf",
"(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;"),
configName);
outputBitmap = env->CallStaticObjectMethod(bitmapCls,
createBitmapMethod,
new_width,
new_height,
java_bitmap_config);
return outputBitmap;
}
/**
* 最近邻插值算法
*/
extern "C"
JNIEXPORT jobject JNICALL
Java_com_kpa_image_MainActivity_scaleBitmapByNearestNeighbor(JNIEnv *env, jobject thiz,
jobject inputBitmap,
jfloat scale) {
// bitmap 转换为openCV的Mat
AndroidBitmapInfo bitmapInfo;
Mat inputMat;
Mat outputMat;
jobject outputBitmap;
if (scale == 1.0) {
return inputBitmap;
}
// 将Android中的Bitmap 对象转为OpenCV 的Mat 对象
if (AndroidBitmap_getInfo(env, inputBitmap, &bitmapInfo) < 0) {
LOGD("转换失败");
return NULL;
}
LOGD("转换成功");
LOGD("图片的格式 %d", bitmapInfo.format);
void *inputPixels;
//获取bitmap 的像素数据(锁定像素缓冲区并检索指向它的指针。这样做可确保像素在应用调用 AndroidBitmap_unlockPixels 之前不会移动)
if (AndroidBitmap_lockPixels(env, inputBitmap, &inputPixels) < 0) {
LOGD("获取像素数据失败");
return NULL;
}
// 创建OpenCV的Mat对象
LOGD("height = %d, width = %d", bitmapInfo.height, bitmapInfo.width);
inputMat.create(bitmapInfo.height, bitmapInfo.width, CV_8UC4);
// 将Bitmap的像素数据拷贝到Mat对象中
memcpy(inputMat.data, inputPixels, inputMat.rows * inputMat.step);
//解锁Bitmap的像素数据
AndroidBitmap_unlockPixels(env, inputBitmap);
// 将图像缩小到原来的一半大小
// int new_width = inputMat.cols / 2;
// int new_height = inputMat.rows / 2;
// 根据缩放比例计算输出图像的宽高
int new_width = static_cast<int>(inputMat.cols * scale);
int new_height = static_cast<int>(inputMat.cols * scale);
//创建输出的Mat对象
outputMat.create(new_height, new_width, CV_8UC4);
// 遍历每个像素
for (int i = 0; i < new_height; i++) {
for (int j = 0; j < new_width; j++) {
//获取原始像素位置
int orig_i = static_cast<int>(i / scale);
int orig_j = static_cast<int>(j / scale);
//将原始像素拷贝到输出Mat对象中
outputMat.at<Vec4b>(i, j) = inputMat.at<Vec4b>(orig_i, orig_j);
}
}
LOGD("图像缩放完成");
outputBitmap = createBitmap(env, new_width, new_height);
LOGD("将OpenCV的Mat对象转换成Java中的Bitmap对象完成");
void *outputPixels;
int result = AndroidBitmap_lockPixels(env, outputBitmap, &outputPixels);
if (result < 0) {
LOGD("outputPixels执行失败 %d", result);
return NULL;
}
LOGD("outputPixels执行完成");
memcpy(outputPixels, outputMat.data, outputMat.rows * outputMat.step);
AndroidBitmap_unlockPixels(env, outputBitmap);
LOGD("执行完成");
// 返回Java中的Bitmap对象
return outputBitmap;
}
/**
* 双线性插值
*/
extern "C"
JNIEXPORT jobject JNICALL
Java_com_kpa_image_MainActivity_scaleBitmapByBilinear(JNIEnv *env, jobject thiz,
jobject input_bitmap, jfloat scale) {
if (scale == 1.0) {
return input_bitmap;
}
// 获取源位图和目标位图的信息
AndroidBitmapInfo bitmapInfo;
void *pixels = nullptr;
//将Android中的Bitmap 对象转为OpenCV 的Mat 对象
if (AndroidBitmap_getInfo(env, input_bitmap, &bitmapInfo) < 0) {
return NULL;
}
//获取原位图的像素
if (AndroidBitmap_lockPixels(env, input_bitmap, &pixels) < 0) {
return NULL;
}
//解锁Bitmap的像素数据
AndroidBitmap_unlockPixels(env, input_bitmap);
LOGD("height = %d, width = %d", bitmapInfo.height, bitmapInfo.width);
//按比例计算目标图像的宽高
int newWidth = static_cast<int>(bitmapInfo.width * scale);
int newHeight = static_cast<int>(bitmapInfo.height * scale);
LOGD("newHeight = %d, newWidth = %d", newHeight, newWidth);
// 原位图像素数组
uint32_t *srcPixels = static_cast<uint32_t *>(pixels);
// 目标位图像素数组
uint32_t *dstPixels = new uint32_t[newWidth * newHeight];
//位图的宽度和新位图的宽度都是从1开始计数的,而像素索引是从0开始计数的。因此,要计算像素索引之间的比率,需要将宽度减一。
float xRatio = static_cast<float>(bitmapInfo.width - 1) / static_cast<float>(newWidth - 1);
float yRatio = static_cast<float>(bitmapInfo.height - 1) / static_cast<float>(newHeight - 1);
for (int y = 0; y < newHeight; ++y) {
for (int x = 0; x < newWidth; ++x) {
float gx = x * xRatio;
float gy = y * yRatio;
int gxi = static_cast<int>(gx);
int gyi = static_cast<int>(gy);
float fracx = gx - gxi;
float fracy = gy - gyi;
uint32_t c00 = srcPixels[gyi * bitmapInfo.width + gxi];
uint32_t c10 = srcPixels[gyi * bitmapInfo.width + gxi + 1];
uint32_t c01 = srcPixels[(gyi + 1) * bitmapInfo.width + gxi];
uint32_t c11 = srcPixels[(gyi + 1) * bitmapInfo.width + gxi + 1];
int r = static_cast<int>((1 - fracx) * (1 - fracy) * (c00 >> 16 & 0xff) +
fracx * (1 - fracy) * (c10 >> 16 & 0xff) +
(1 - fracx) * fracy * (c01 >> 16 & 0xff) +
fracx * fracy * (c11 >> 16 & 0xff));
int g = static_cast<int>((1 - fracx) * (1 - fracy) * (c00 >> 8 & 0xff) +
fracx * (1 - fracy) * (c10 >> 8 & 0xff) +
(1 - fracx) * fracy * (c01 >> 8 & 0xff) +
fracx * fracy * (c11 >> 8 & 0xff));
int b = static_cast<int>((1 - fracx) * (1 - fracy) * (c00 & 0xff) +
fracx * (1 - fracy) * (c10 & 0xff) +
(1 - f
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【项目资源】: 包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。
资源推荐
资源详情
资源评论
收起资源包目录
毕设&课设&项目&实训-图像缩放算法总汇,使用C++实现。包含创建的插值算法和基于变换的算法.zip (392个子文件)
gradlew.bat 3KB
native-lib.cpp 9KB
.gitignore 260B
.gitignore 47B
.gitignore 6B
build.gradle 2KB
settings.gradle 408B
build.gradle 295B
gradlew 6KB
core_c.h 126KB
msa_macros.h 81KB
types_c.h 70KB
kmeans_index.h 66KB
imgproc_c.h 50KB
dist.h 40KB
cvdef.h 36KB
constants_c.h 30KB
cv_cpu_helper.h 29KB
hierarchical_clustering_index.h 26KB
autotuned_index.h 21KB
kdtree_single_index.h 20KB
kdtree_index.h 20KB
lsh_table.h 18KB
types_c.h 18KB
lsh_index.h 15KB
result_set.h 15KB
index_testing.h 11KB
highgui_c.h 10KB
any.h 8KB
cv_cpu_dispatch.h 8KB
hdf5.h 7KB
heap.h 7KB
allocator.h 6KB
all_indices.h 6KB
composite_index.h 6KB
nn_index.h 6KB
saving.h 6KB
simplex_downhill.h 6KB
videoio_c.h 6KB
calib3d_c.h 5KB
cap_ios.h 5KB
interface.h 5KB
dynamic_bitset.h 4KB
defines.h 4KB
random.h 4KB
params.h 4KB
logger.h 4KB
linear_index.h 4KB
ground_truth.h 3KB
matrix.h 3KB
cvconfig.h 3KB
object_factory.h 3KB
sampling.h 3KB
ios.h 3KB
timer.h 3KB
general.h 2KB
config.h 2KB
constants_c.h 2KB
interface.h 1KB
macosx.h 731B
interface.h 551B
constants_c.h 462B
constants_c.h 398B
dummy.h 197B
imgcodecs_c.h 145B
imgproc.hpp 241KB
color_detail.hpp 219KB
calib3d.hpp 217KB
mat.hpp 161KB
intrin_avx512.hpp 157KB
core.hpp 151KB
intrin_sse.hpp 132KB
intrin_avx.hpp 131KB
intrin_lasx.hpp 131KB
intrin_wasm.hpp 107KB
intrin_rvv.hpp 104KB
intrin_cpp.hpp 101KB
intrin_rvv071.hpp 98KB
intrin_neon.hpp 96KB
ml.hpp 90KB
intrin_rvv_scalable.hpp 89KB
dnn.hpp 87KB
mat.inl.hpp 87KB
core.hpp 78KB
imgproc.hpp 78KB
types.hpp 71KB
intrin_msa.hpp 71KB
features2d.hpp 71KB
intrin_vsx.hpp 66KB
videoio.hpp 66KB
quaternion.hpp 65KB
opencl_clblas.hpp 63KB
vsx_utils.hpp 51KB
vec_math.hpp 49KB
matx.hpp 48KB
persistence.hpp 46KB
cuda.hpp 46KB
objdetect.hpp 42KB
sse_utils.hpp 41KB
tracking.hpp 41KB
共 392 条
- 1
- 2
- 3
- 4
资源评论
妄北y
- 粉丝: 9670
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功