Поверните изображение в соответствии с переданной ориентацией на функции, используя собственный код
Я хочу повернуть изображение в соответствии с передачей ориентации функции в моей функции rotateBitmap().
Я взял ссылку на этот метод из этой удивительной библиотеки.
Что я хочу сделать:
Я хочу повернуть изображение в соответствии с передачей ориентации в функции после этого, я хочу
примените эффект серого масштабирования к изображению, а затем, если хотите уменьшить изображение и вернуть эскиз изображения к вызывающей активности.
Здесь ниже я вставил свой собственный код.
Что я пробовал до сих пор:
#include <jni.h>
#include <android/log.h>
#include <android/bitmap.h>
#include <stdio.h>
#include <cstring>
#include <unistd.h>
#define LOG_TAG "libphotophun"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
typedef struct
{
uint8_t alpha;
uint8_t red;
uint8_t green;
uint8_t blue;
} argb;
class JniBitmap
{
public:
uint32_t* _storedBitmapPixels;
AndroidBitmapInfo _bitmapInfo;
JniBitmap()
{
_storedBitmapPixels = NULL;
}
};
extern "C"
{
//store
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_jniStoreBitmapData(
JNIEnv * env, jobject obj, jobject bitmap);
//get
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_jniGetBitmapFromStoredBitmapData(
JNIEnv * env, jobject obj, jobject handle);
//free
JNIEXPORT void JNICALL Java_com_example_ndksampleproject_MainActivity_jniFreeBitmapData(
JNIEnv * env, jobject obj, jobject handle);
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_rotateBitmap(
JNIEnv * env, jobject obj, jobject bitmap,int rotation);
}
/**free bitmap*/ //
JNIEXPORT void JNICALL Java_com_example_ndksampleproject_MainActivity_jniFreeBitmapData(
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
delete[] jniBitmap->_storedBitmapPixels;
jniBitmap->_storedBitmapPixels = NULL;
delete jniBitmap;
}
/**restore java bitmap (from JNI data)*/ //
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_jniGetBitmapFromStoredBitmapData(
JNIEnv * env, jobject obj, jobject handle)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
{
LOGD("no bitmap data was stored. returning null...");
return NULL;
}
//
//creating a new bitmap to put the pixels into it - using Bitmap Bitmap.createBitmap (int width, int height, Bitmap.Config config) :
//
jclass bitmapCls = env->FindClass("android/graphics/Bitmap");
jmethodID createBitmapFunction = 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");
jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID(
bitmapConfigClass, "valueOf",
"(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass,
valueOfBitmapConfigFunction, configName);
jobject newBitmap = env->CallStaticObjectMethod(bitmapCls,
createBitmapFunction, jniBitmap->_bitmapInfo.width,
jniBitmap->_bitmapInfo.height, bitmapConfig);
//
// putting the pixels into the new bitmap:
//
int ret;
void* bitmapPixels;
if ((ret = AndroidBitmap_lockPixels(env, newBitmap, &bitmapPixels)) < 0)
{
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return NULL;
}
uint32_t* newBitmapPixels = (uint32_t*) bitmapPixels;
int pixelsCount = jniBitmap->_bitmapInfo.height
* jniBitmap->_bitmapInfo.width;
memcpy(newBitmapPixels, jniBitmap->_storedBitmapPixels,
sizeof(uint32_t) * pixelsCount);
AndroidBitmap_unlockPixels(env, newBitmap);
//LOGD("returning the new bitmap");
return newBitmap;
}
/**store java bitmap as JNI data*/ //
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_jniStoreBitmapData(
JNIEnv * env, jobject obj, jobject bitmap)
{
AndroidBitmapInfo bitmapInfo;
uint32_t* storedBitmapPixels = NULL;
//LOGD("reading bitmap info...");
int ret;
if ((ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0)
{
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return NULL;
}
//LOGD("width:%d height:%d stride:%d", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride);
if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
{
LOGE("Bitmap format is not RGBA_8888!");
return NULL;
}
//
//read pixels of bitmap into native memory :
//
//LOGD("reading bitmap pixels...");
void* bitmapPixels;
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels)) < 0)
{
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return NULL;
}
uint32_t* src = (uint32_t*) bitmapPixels;
storedBitmapPixels = new uint32_t[bitmapInfo.height * bitmapInfo.width];
int pixelsCount = bitmapInfo.height * bitmapInfo.width;
memcpy(storedBitmapPixels, src, sizeof(uint32_t) * pixelsCount);
AndroidBitmap_unlockPixels(env, bitmap);
JniBitmap *jniBitmap = new JniBitmap();
jniBitmap->_bitmapInfo = bitmapInfo;
jniBitmap->_storedBitmapPixels = storedBitmapPixels;
return env->NewDirectByteBuffer(jniBitmap, 0);
}
JNIEXPORT jobject JNICALL Java_com_example_ndksampleproject_MainActivity_rotateBitmap(JNIEnv * env, jobject obj, jobject bitmap,int rotation,jobject handle)
{
JniBitmap* jniBitmap =jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if(rotation==90)
{
//jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
uint32_t newHeight = jniBitmap->_bitmapInfo.width;
jniBitmap->_bitmapInfo.width = newWidth;
jniBitmap->_bitmapInfo.height = newHeight;
uint32_t* newBitmapPixels = new uint32_t[newWidth * newHeight];
int whereToGet = 0;
// XY. ... ... ..X
// ...>Y..>...>..Y
// ... X.. .YX ...
for (int x = 0; x < newWidth; ++x)
for (int y = newHeight - 1; y >= 0; --y)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[newWidth * y + x] = pixel;
}
//delete[] previousData;
jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
else if(rotation==180)
{
//jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t width = jniBitmap->_bitmapInfo.width;
uint32_t height = jniBitmap->_bitmapInfo.height;
uint32_t* newBitmapPixels = new uint32_t[width * height];
int whereToGet = 0;
// XY. ...
// ...>...
// ... .YX
jniBitmap->_storedBitmapPixels = newBitmapPixels;
for (int y = height - 1; y >= 0; --y)
for (int x = width - 1; x >= 0; --x)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[width * y + x] = pixel;
}
//delete[] previousData;
jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
else if(rotation==270)
{
//jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
uint32_t newHeight = jniBitmap->_bitmapInfo.width;
jniBitmap->_bitmapInfo.width = newWidth;
jniBitmap->_bitmapInfo.height = newHeight;
uint32_t* newBitmapPixels = new uint32_t[newWidth * newHeight];
int whereToGet = 0;
// XY. ..X ... ...
// ...>..Y>...>Y..
// ... ... .YX X..
jniBitmap->_storedBitmapPixels = newBitmapPixels;
for (int x = newWidth - 1; x >= 0; --x)
for (int y = 0; y < newHeight; ++y)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[newWidth * y + x] = pixel;
}
//delete[] previousData;
jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
return jniBitmap;
}
Лог cat::
Compile++ thumb : photophun <= photophun.cpp
In file included from D:/Workspace/NDKSampleProject/jni/photophun.cpp:2:0:
D:/android-ndk-r8b/platforms/android-14/arch-arm/usr/include/jni.h:592:13: note: the mangling of 'va_list' has changed in GCC 4.4
D:/Workspace/NDKSampleProject/jni/photophun.cpp: In function '_jobject* Java_com_example_ndksampleproject_MainActivity_rotateBitmap(JNIEnv*, jobject, jobject, int, jobject)':
D:/Workspace/NDKSampleProject/jni/photophun.cpp:154:4: error: return-statement with no value, in function returning 'jobject {aka _jobject*}' [-fpermissive]
D:/Workspace/NDKSampleProject/jni/photophun.cpp:179:4: error: return-statement with no value, in function returning 'jobject {aka _jobject*}' [-fpermissive]
D:/Workspace/NDKSampleProject/jni/photophun.cpp:204:4: error: return-statement with no value, in function returning 'jobject {aka _jobject*}' [-fpermissive]
D:/Workspace/NDKSampleProject/jni/photophun.cpp:226:9: error: cannot convert 'JniBitmap*' to 'jobject {aka _jobject*}' in return
/cygdrive/d/android-ndk-r8b/build/core/build-binary.mk:255: recipe for target `/cygdrive/d/Workspace/NDKSampleProject/obj/local/armeabi/objs/photophun/photophun.o' failed
make: *** [/cygdrive/d/Workspace/NDKSampleProject/obj/local/armeabi/objs/photophun/photophun.o] Error 1
Пожалуйста, дайте мне знать, если вам нужно что-нибудь с моей стороны.
Пожалуйста, помогите мне, поскольку мне очень нужна эта задача, чтобы решить проблему OOM.
Большое спасибо заранее....
EDIT::
extern "C"
{
JNIEXPORT void JNICALL com_example_ndksampleproject_MainActivity_rotateBitmap(
JNIEnv * env, jobject obj, jobject bitmap,int rotation);
}
JNIEXPORT void JNICALL com_example_ndksampleproject_MainActivity_rotateBitmap(JNIEnv * env, jobject obj, jobject bitmap,uint32_t rotation,jobject handle)
{
JniBitmap* jniBitmap =jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if(rotation==90)
{
jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
uint32_t newHeight = jniBitmap->_bitmapInfo.width;
jniBitmap->_bitmapInfo.width = newWidth;
jniBitmap->_bitmapInfo.height = newHeight;
uint32_t* newBitmapPixels = new uint32_t[newWidth * newHeight];
int whereToGet = 0;
// XY. ... ... ..X
// ...>Y..>...>..Y
// ... X.. .YX ...
for (int x = 0; x < newWidth; ++x)
for (int y = newHeight - 1; y >= 0; --y)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[newWidth * y + x] = pixel;
}
delete[] previousData;
//jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
else if(rotation==180)
{
jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t width = jniBitmap->_bitmapInfo.width;
uint32_t height = jniBitmap->_bitmapInfo.height;
uint32_t* newBitmapPixels = new uint32_t[width * height];
int whereToGet = 0;
// XY. ...
// ...>...
// ... .YX
jniBitmap->_storedBitmapPixels = newBitmapPixels;
for (int y = height - 1; y >= 0; --y)
for (int x = width - 1; x >= 0; --x)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[width * y + x] = pixel;
}
delete[] previousData;
//jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
else if(rotation==270)
{
jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL)
return;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t newWidth = jniBitmap->_bitmapInfo.height;
uint32_t newHeight = jniBitmap->_bitmapInfo.width;
jniBitmap->_bitmapInfo.width = newWidth;
jniBitmap->_bitmapInfo.height = newHeight;
uint32_t* newBitmapPixels = new uint32_t[newWidth * newHeight];
int whereToGet = 0;
// XY. ..X ... ...
// ...>..Y>...>Y..
// ... ... .YX X..
jniBitmap->_storedBitmapPixels = newBitmapPixels;
for (int x = newWidth - 1; x >= 0; --x)
for (int y = 0; y < newHeight; ++y)
{
//take from each row (up to bottom), from left to right
uint32_t pixel = previousData[whereToGet++];
newBitmapPixels[newWidth * y + x] = pixel;
}
delete[] previousData;
//jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
//return jniBitmap;
}
Я вызвал собственный метод this Way::
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap tempBmp=null;
ByteBuffer _handler =null;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.item_rotate_90:
options.inPreferredConfig = Config.ARGB_8888;
bitmapOrig = BitmapFactory.decodeResource(this.getResources(), R.drawable.sampleimage,options);
rotateBitmap(bitmapOrig,90,_handler);
tempBmp=getBitmapAndFree();
if(tempBmp!=null)
{
ivDisplay.setImageBitmap(tempBmp);
}
break;
LogCat::
FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Native method not found: com.example.ndksampleproject.MainActivity.rotateBitmap:(Landroid/graphics/Bitmap;ILjava/nio/ByteBuffer;)V
at com.example.ndksampleproject.MainActivity.rotateBitmap(Native Method)
at com.example.ndksampleproject.MainActivity.onOptionsItemSelected(MainActivity.java:113)
at android.app.Activity.onMenuItemSelected(Activity.java:2612)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1061)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
Ответы
Ответ 1
Код, который я сделал, уже поддерживает вращение. просто посмотрите пример проекта, чтобы узнать, как его назвать.
Кроме того, серое масштабирование не должно быть слишком сложной операцией для реализации кода С++, который я сделал. Я уверен, что есть примеры этого в Интернете.
Что касается понижающей дискретизации, я не делал этого так, как это было много работы, но я добавил масштабирование изображений, которые уже декодированы (что означает, что они хранятся в виде растровых объектов).
Тем не менее, вы всегда можете уменьшить масштаб, используя обычный способ Google или мой путь (нижний код).