سؤال

لدي تطبيق ويب مكتوب بلغة Java (Spring، Hibernate/JPA، Struts2) حيث يمكن للمستخدمين تحميل الصور وتخزينها في نظام الملفات.أرغب في تغيير حجم تلك الصور بحيث تكون ذات حجم ثابت للعرض على الموقع.ما المكتبات أو الوظائف المضمنة التي ستقدم أفضل النتائج؟سأأخذ في الاعتبار المعايير التالية عند اتخاذ قراري (بهذا الترتيب):

  • مجاني/مفتوح المصدر (ضروري)
  • سهل التنفيذ
  • جودة النتائج
  • أداء
  • حجم الملف القابل للتنفيذ
هل كانت مفيدة؟

المحلول

الق نظرة على Java Image I/O API لقراءة/كتابة الصورة.ثم استخدام أفينيترانسفورم لتغيير الحجم.

أيضًا، هنا مثال كامل باستخدام java.awt.Image.

نصائح أخرى

أود حقا أن أوصي بالعطاء com.imgscalr نظرة.

تم إصداره بموجب ترخيص Apache 2، وتم استضافته على جيثب, ، تم نشره في عدد قليل من تطبيقات الويب بالفعل، وله طريقة بسيطة جدًا، ولكن واجهة برمجة التطبيقات (API) الموثقة بشكل متقن, يحتوي على رمز يعمل على التغلب على خطأين رئيسيين في الصور في JDK من أجلك بشفافية ولن تلاحظ ذلك إلا إذا بدأت فجأة في الحصول على صور "سوداء" بعد عملية واسعة النطاق أو نتائج سيئة المظهر، مما يمنحك أفضل نتائج مظهر ممكنة متاحة في Java، وهو متاح عبر Maven بالإضافة إلى ملف ZIP وهو مجرد فئة واحدة.

الاستخدام الأساسي يبدو كالتالي:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 320);

هذه هي أبسط مكالمة حيث ستقوم المكتبة بإجراء أفضل تخمين للجودة، واحترام نسب الصورة الخاصة بك، واحتواء النتيجة داخل مربع محيط بحجم 320 × 320.ملاحظة، المربع المحيط هو فقط الحد الأقصى للوزن/الارتفاع المستخدم، نظرًا لأنه يتم احترام نسب صورتك، فإن الصورة الناتجة ستظل تحترم ذلك، على سبيل المثال 320 × 200.

إذا كنت تريد تجاوز الوضع التلقائي وإجباره على إعطائك أفضل النتائج وحتى تطبيق مرشح معتدل جدًا للتنعيم على النتيجة بحيث تبدو أفضل (خاصة جيدة للصور المصغرة)، فستبدو هذه المكالمة كما يلي:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                       150, 100, Scalr.OP_ANTIALIAS);

هذه كلها مجرد أمثلة، واجهة برمجة التطبيقات (API) واسعة النطاق وتغطي كل شيء بدءًا من حالات الاستخدام فائقة البساطة وحتى حالات الاستخدام المتخصصة للغاية.يمكنك أيضًا تمرير BufferedImageOps الخاص بك ليتم تطبيقه على الصورة (وستقوم المكتبة تلقائيًا بإصلاح خطأ BufferedImageOp JDK الذي دام 6 سنوات لك!)

هناك الكثير من الأشياء التي يمكن أن تقوم بها المكتبة من أجلك في تغيير حجم الصور في Java بنجاح، على سبيل المثال، الاحتفاظ دائمًا بالصورة في أحد أفضل أنواع صور RGB أو ARGB المدعومة أثناء التشغيل عليها.تحت الأغطية، يعود مسار معالجة الصور Java2D إلى مسار برامج أدنى إذا كان نوع الصورة المستخدم لأي عمليات صورة مدعومًا بشكل سيئ.

إذا كان كل ذلك يبدو وكأنه الكثير من الصداع، فهو نوعاً ما...ولهذا السبب قمت بتأليف المكتبة وفتحها من المصدر، حتى يتمكن الأشخاص من تغيير حجم صورهم والمضي قدمًا في حياتهم دون الحاجة إلى القلق بشأن ذلك.

امل ان يساعد.

النظر في أيضا ل تحجيم صورة جافا مكتبة.لقد أنشأ صورًا ذات جودة أفضل من ImageIO.

أعلم أن هذا سؤال قديم جدًا، ولكن لدي الحل الخاص بي باستخدام Java API القياسي

import java.awt.*;
import java.awt.event.*;
import javax.imageio.*
import java.awt.image.*;

BufferedImage im, bi, bi2;
Graphics2D gfx;
int imWidth, imHeight, dstWidth, dstHeight;
int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500;

im = ImageIO.read(new File(filePath));
imWidth = im.getWidth(null);
imHeight = im.getHeight(null);

dstWidth = DESIRED_WIDTH;
dstHeight = (dstWidth * imHeight) / imWidth;

bi = new BufferedImage(dstWidth, dstHeight, im.getType());

gfx = bi.createGraphics();
gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null);

bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType());
gfx = bi2.createGraphics();

gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null);

ImageIO.write(bi2, "jpg", new File(filePath));

أنا متأكد من أنه يمكن تحسينها وتكييفها.

أفضل أداة لتحرير الصور هي ImageMagick وهو مفتوح المصدر.

هناك واجهتان للغة Java:

JMagick الذي يستخدم واجهة JNI لـ ImageMagick

و

com.im4java ما هي واجهة سطر الأوامر لـ ImageMagick

لقد حاولت مقارنة imgscalr بـ Java 1.6 القياسي ولا أستطيع أن أقول إنه أفضل.

ما حاولت هو

BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height);

و

  Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH);
  BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null),  scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
  bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null);

لقد حصل اختبار عيني لمدة 5 دقائق على انطباع بأن الشيء الثاني (Java 1.6 الخالص) ينتج عنه نتائج أفضل.

وجدت أن هذا أسرع:

public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight,
                                              final Object hint) {
    final int type = BufferedImage.TYPE_INT_RGB;
    int drawHeight = targetHeight;
    int drawWidth = targetWidth;
    final int imageWidth = img.getWidth();
    final int imageHeight = img.getHeight();
    if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) {
        logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale");
        return img;
    }
    final double sar = ((double) imageWidth) / ((double) imageHeight);
    if (sar != 0) {
        final double tar = ((double) targetWidth) / ((double) targetHeight);
        if ((Math.abs(tar - sar) > .001) && (tar != 0)) {
            final boolean isSoureWider = sar > (targetWidth / targetHeight);
            if (isSoureWider) {
                drawHeight = (int) (targetWidth / sar);
            }
            else {
                drawWidth = (int) (targetHeight * sar);
            }
        }
    }
    logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight);
    final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type);
    try {
        final Graphics2D g2 = result.createGraphics();
        try {
            if (hint != null) {
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            }
            g2.drawImage(img, 0, 0, drawWidth, drawHeight, null);
        }
        finally {
            g2.dispose();
        }
        return result;
    }
    finally {
        result.flush();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top