AMcoder - javascript, python, java, html, php, sql

Ստեղծեք QR-կոդ վեկտորային պատկերում

Ես կարող եմ հաջողությամբ ստեղծել QR Code PNG պատկերներ ZXing-ի միջոցով, բայց հեշտ ճանապարհ չկա ելքը SVG կամ EPS ստանալու համար:

Ինչպե՞ս կարող եմ վեկտորային պատկեր ստեղծել BitMatrix օբյեկտից, որը ստեղծվել է QRCodeWriter-ի կողմից:


  • Ես կասկածի տակ կդնեի դրա անհրաժեշտությունը վեկտորային ձևաչափով: QR կոդը կատարյալ քառակուսի սև և սպիտակ պիքսելների հավաքածու է: Այն կմեծացնի անսահմանությունը՝ առանց հավատարմության կորստի: Այսպիսով, ես կասեի, պահպանեք որպես PNG: 29.05.2012
  • այս աշխարհում դեռևս կան սարքեր, որոնք չեն կարողանում աշխատել PNG-ով: Լազերային փորագրիչը դրանցից մեկն է: Ահա թե ինչու ինձ անհրաժեշտ էր վեկտորային ձևաչափ 30.05.2012

Պատասխանները:


1

Հին հարց ես գիտեմ, բայց բոլորի համար, ովքեր գալիս են, ովքեր փնտրում են, թե ինչպես դա անել... շատ հեշտ է միացնել ZXing-ին JFreeSVG-ին (http://www.jfree.org/jfreesvg), օրինակ.

package org.jfree.demo;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import org.jfree.graphics2d.svg.SVGGraphics2D;
import org.jfree.graphics2d.svg.SVGUtils;

public class QRCodes {

    public static void main(String[] args) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode("http://www.jfree.org/jfreesvg", 
                BarcodeFormat.QR_CODE, 160, 160);
        int w = bitMatrix.getWidth();
        SVGGraphics2D g2 = new SVGGraphics2D(w, w);
        g2.setColor(Color.BLACK);
    for (int xIndex = 0; xIndex < w; xIndex = xIndex + bitMatrix.getRowSize()) {
        for (int yIndex = 0; yIndex < w; yIndex = yIndex + bitMatrix.getRowSize()) {
            if (bitMatrix.get(xIndex, yIndex)) {
                g2.fillRect(xIndex, yIndex, bitMatrix.getRowSize(), bitMatrix.getRowSize());

            }
        }
    }

        SVGUtils.writeToSVG(new File("qrtest.svg"), g2.getSVGElement());
    }

}
03.05.2016
  • Սա ինձ մոտ չաշխատեց. ստեղծված SVG-ն վավեր QR կոդ չէր և զգալիորեն տարբերվում էր BitMatrix-ի PNG պատկերից: Փակ, բայց վնասված: 19.01.2021
  • Այն չի աշխատում որոշ չափերի համար, օրինակ՝ 144x144 24.04.2021

  • 2

    Դուք նույնիսկ կարող եք դա անել միայն zxing-ով առանց լրացուցիչ գրադարանների.

    QRCodeWriter qrCodeWriter = new QRCodeWriter();
    Map<EncodeHintType, Object> hints = new HashMap<>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
    hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
    
    BitMatrix bitMatrix = qrCodeWriter.encode(payload, BarcodeFormat.QR_CODE, 543, 543, hints);
    
    StringBuilder sbPath = new StringBuilder();
    int width = bitMatrix.getWidth();
    int height = bitMatrix.getHeight();
    int rowSize = bitMatrix.getRowSize();
    BitArray row = new BitArray(width);
    for(int y = 0; y < height; ++y) {
        row = bitMatrix.getRow(y, row);
        for(int x = 0; x < width; ++x) {
            if (row.get(x)) {
                sbPath.append(" M"+x+","+y+"h1v1h-1z");
            }
        }
    }
    
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    sb.append("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ").append(width).append(" ").append(height).append("\" stroke=\"none\">\n");
    sb.append("<style type=\"text/css\">\n");
    sb.append(".black {fill:#000000;}\n");
    sb.append("</style>\n");
    sb.append("<path class=\"black\"  d=\"").append(sbPath.toString()).append("\"/>\n");
    sb.append("</svg>\n");
    

    Խնդրում ենք նկատի ունենալ, որ վերը նշված լուծումը շատ ավելի արդյունավետ է հիշողության սպառման առումով, քան Batik's DOM-ն օգտագործող լուծումը:

    11.03.2020
  • դու փրկեցիր իմ օրը! շատ շնորհակալ եմ, դա հենց այն է, ինչ անհրաժեշտ էր) 25.06.2020
  • Սա աշխատում է, բայց QR կոդի համար ելքը մի փոքր... մեծ է թվում: 105 Կբ, ընդդեմ 359 բայթ png-ի համար: Առցանց գեներատորը կառավարել է նույն URL-ը 2 Կբ-ով: Կարծում եմ, որ այս մոտեցումը հիմնավոր է, բայց օպտիմալացման կարիք ունի: 19.01.2021
  • Լուծված է. «encode()»-ում չափի ճշգրտումն օգնում է կառավարել ելքը և լավ է աշխատում: Շնորհակալություն այս կոկիկ լուծման համար: 19.01.2021
  • Մասնավորապես, զրոները որպես լայնություն և բարձրություն փոխանցելը կստիպի ZXing-ը արտադրել QR կոդի չափերին համապատասխանող մատրիցը (ներառյալ հանգիստ գոտին): 16.03.2021
  • style տարրն այստեղ ավելորդ է (լրացումը ուղու համար լռելյայն սև է. տե՛ս developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill#path): Անհասկանալի է, թե ինչու են այստեղ օգտագործվում երկու լարային կառուցողներ. ավելի պարզ է պարզապես ավելացնել XML-ի առաջին մասը մեկ շինարարի վրա, այնուհետև շրջել զանգվածի միջով՝ ավելացնելով պիքսելներ, ապա ավելացնել մնացած XML-ը: M-ից առաջ տարածությունը լիովին ընտրովի է և միայն օգնում է վերջնական արդյունքը ընթեռնելի դարձնել: 17.03.2021

  • 3

    Ամենահեշտ ձևը, որը ես գտա, iText-ով PDF ստեղծելն էր, այնուհետև ստացված PDF-ը EPS-ի կամ SVG-ի վերածելն էր: Ահա PDF-ը ստեղծելու կոդը.

       @Test
       public void testQRtoPDF() throws WriterException, FileNotFoundException, DocumentException, UnsupportedEncodingException {
          final int s = 600;
          int r = 1;
    
          Charset charset = Charset.forName( "UTF-8" );
          CharsetEncoder encoder = charset.newEncoder();
          byte[] b = null;
          try {
             // Convert a string to UTF-8 bytes in a ByteBuffer
             ByteBuffer bbuf = encoder.encode( CharBuffer.wrap(
                         "1éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò1" +
                                     "2éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò2" +
                                     "3éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò3" +
                                     "4éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò4" +
                                     "5éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò5" +
                                     "6éöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùòïëéöàäèüùò6" ) );
             b = bbuf.array();
          } catch ( CharacterCodingException e ) {
             System.out.println( e.getMessage() );
          }
    
          String content = new String( b, "UTF-8" );
          QRCodeWriter qrCodeWriter = new QRCodeWriter();
          Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>( 2 );
          hints.put( EncodeHintType.CHARACTER_SET, "UTF-8" );
          BitMatrix qrCode = qrCodeWriter.encode( content, BarcodeFormat.QR_CODE, s, s, hints );
    
          Document doc = new Document( new Rectangle( s, s ) );
          PdfWriter pdfWriter = PdfWriter.getInstance( doc, new FileOutputStream( "qr-code.pdf" ) );
          doc.open();
          PdfContentByte contentByte = pdfWriter.getDirectContent();
          contentByte.setColorFill( BaseColor.BLACK );
    
          boolean d = false;
          for ( int x = 0; x < qrCode.getWidth(); x += r ) {
             for ( int y = 0; y < qrCode.getHeight(); y += r ) {
                if ( qrCode.get( x, y ) ) {
                   contentByte.rectangle( x, s - y, r, r );
                   contentByte.fill();
                   contentByte.stroke();
                }
             }
          }
    
          doc.close();
       }
    

    Այնուհետև ես օգտագործում եմ պատկերի մոգություն փոխակերպման համար: Այսպես.

    convert qr-code.pdf qr-code.eps
    

    նույնը ՉԻ կարող անել svg-ի համար

    convert qr-code.pdf qr-code.svg
    

    սա չի աշխատում

    Ես փորձարկեցի այս կոդը որոշ երկար բովանդակությամբ և այն աշխատում էր մինչև 600 նիշով: Սա, հավանաբար, պայմանավորված է հեռախոսի կամ էկրանի տեսախցիկի ճշգրտությամբ:

    Հուսով եմ, որ սա օգնում է ինչ-որ մեկին

    28.05.2012
  • Եթե ​​ձեզ հարկավոր չէ UTF-8, կարող եք բաց թողնել ByteBuffer-ը և հուշումները և ուղղակիորեն կոդավորել ձեր տողը 28.05.2012
  • Անձամբ ես կօգտագործեի inkscape հետագծումը PNG-ում դա անելու համար, բայց եթե սա պատասխանն աշխատում է, դուք կարող եք օգտագործել այն: 20.04.2014

  • 4

    Դուք կարող եք օգտագործել Apache BatikJFreeSVG-ի փոխարեն, եթե ցանկանում եք ավելի ազատ լիցենզիա: Դա հատկապես իմաստալից է, երբ դուք օգտագործում եք Apache FOP-ը, որը ներառում է Apache Batik-ը որպես անցողիկ կախվածություն:

    Ահա ճշգրտված տարբերակը. Գաղափարի և օրիգինալ ծածկագրի վարկերը պատկանում են Դեյվիդ Գիլբերտին:

    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.WriterException;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    import org.apache.batik.anim.dom.SVGDOMImplementation;
    import org.w3c.dom.DOMImplementation;
    import org.w3c.dom.svg.SVGDocument;
    
    import java.awt.*;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    
    public class QRCodesBatik {
    
        public static void main(String[] args) throws WriterException, IOException {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode("https://xmlgraphics.apache.org/batik/",
                    BarcodeFormat.QR_CODE, 800, 800);
    
            // Create a document with the appropriate namespace
            DOMImplementation domImpl = SVGDOMImplementation.getDOMImplementation();
            SVGDocument document = (SVGDocument) domImpl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null);
            // Create an instance of the SVG Generator
            org.apache.batik.svggen.SVGGraphics2D g2 = new org.apache.batik.svggen.SVGGraphics2D(document);
    
            // draw onto the SVG Graphics object
            g2.setColor(Color.BLACK);
    
            for (int xIndex = 0; xIndex < bitMatrix.getWidth(); xIndex = xIndex + bitMatrix.getRowSize()) {
                for (int yIndex = 0; yIndex < bitMatrix.getWidth(); yIndex = yIndex + bitMatrix.getRowSize()) {
                    if (bitMatrix.get(xIndex, yIndex)) {
                        g2.fillRect(xIndex, yIndex, bitMatrix.getRowSize(), bitMatrix.getRowSize());
                    }
                }
            }
    
            try (Writer out = new OutputStreamWriter(new FileOutputStream(new File("qrtest.svg")), "UTF-8")) {
                g2.stream(out, true);
            }
        }
    }
    
    26.08.2019

    5

    Svg ձևաչափը նախատեսված է ուղղանկյունների մի շարք, որը կառուցում է BitMatrix-ը: Ձևաչափի գաղափարը պատկերի լուծումն է, որը չպետք է ազդի չափի որևէ աճի վրա: Օրինակ, @siom-ի լուծումը ստեղծում է 1x1 ուղղանկյուններ բոլոր պիքսելների համար (այդ իսկ պատճառով այն ստեղծում է հսկայական ֆայլ): Ես այդ լուծումը դասում եմ որպես բիրտ ուժի մոտեցում այս խնդրին։

    Ես ավելի լավ լուծում եմ մշակել, որն աշխատում է O(n^2-ում): Այն սկանավորում է ամբողջ bitMatrix-ը և սկզբում հայտնաբերում է առավելագույն երկարության քառակուսին յուրաքանչյուր կետում, այնուհետև այն փորձում է ուղղանկյունի հասցնել քառակուսին յուրաքանչյուր հարթության մեջ: Վերջապես այն գծում է բոլոր հնարավոր ուղղանկյունները և քառակուսիները տարբեր չափերի:

    import com.google.zxing.common.BitMatrix;
    import java.awt.Color;
    import java.awt.Point;
    import java.nio.charset.StandardCharsets;
    import java.util.HashSet;
    import java.util.Set;
    import org.jfree.graphics2d.svg.SVGGraphics2D;
    
    public class SvgUtils {
    
      public static byte[] createSvgImage(BitMatrix bitMatrix){
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        Set<Point> visitedPoints = new HashSet<>();
        SVGGraphics2D g2 = new SVGGraphics2D(width, height);
        g2.setColor(Color.BLACK);
        for (int x = 0; x < width; x++) {
          for (int y = 0; y < height; y++) {
            Point maxRectangleLength = getMaxRectangleLength(new Point(x, y), bitMatrix, visitedPoints);
            if(maxRectangleLength != null) {
              g2.fillRect(x, y, maxRectangleLength.x, maxRectangleLength.y);
              y += maxRectangleLength.y-1;
            }
          }
        }
        return g2.getSVGDocument().getBytes(StandardCharsets.UTF_8);
      }
    
      private static int getMaxSquareLength(Point startPoint, BitMatrix bitMatrix, Set<Point> visitedPoints){
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        int maxLength = 0;
        while(startPoint.x + maxLength < width && startPoint.y + maxLength < height) {
          for (int xOffSett = 0; xOffSett < maxLength; xOffSett++) {
            if (!bitMatrix.get(startPoint.x + xOffSett, startPoint.y + maxLength) || visitedPoints.contains(new Point(startPoint.x + xOffSett, startPoint.y + maxLength))) {
              return maxLength;
            }
          }
          for (int yOffset = 0; yOffset <= maxLength; yOffset++) {
            if (!bitMatrix.get(startPoint.x + maxLength, startPoint.y + yOffset) || visitedPoints.contains(new Point(startPoint.x + maxLength, startPoint.y + yOffset))) {
              return maxLength;
            }
          }
          for (int xOffSett = 0; xOffSett < maxLength; xOffSett++) {
            visitedPoints.add(new Point(startPoint.x + xOffSett, startPoint.y + maxLength));
          }
          for (int yOffset = 0; yOffset <= maxLength; yOffset++) {
            visitedPoints.add(new Point(startPoint.x + maxLength, startPoint.y + yOffset));
          }
          maxLength++;
        }
        return maxLength;
      }
    
      private static Point getMaxRectangleLength(Point startPoint, BitMatrix bitMatrix, Set<Point> visitedPoints){
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        int maxSquareLength = getMaxSquareLength(startPoint, bitMatrix, visitedPoints);
        if(maxSquareLength == 0)
          return null;
        int maxWidth = maxSquareLength-1;
        int maxHeight = maxSquareLength-1;
        boolean searchFinished = false;
        while(!searchFinished && startPoint.y + ++maxHeight < height) {
          for (int xOffSett = 0; xOffSett < maxSquareLength; xOffSett++) {
            if (!bitMatrix.get(startPoint.x + xOffSett, startPoint.y + maxHeight) ||
                visitedPoints.contains(new Point(startPoint.x + xOffSett, startPoint.y + maxHeight))) {
              searchFinished = true;
              break;
            }
          }
        }
        searchFinished = false;
        while(!searchFinished && startPoint.x + ++maxWidth < width) {
          for (int yOffSett = 0; yOffSett < maxSquareLength; yOffSett++) {
            if (!bitMatrix.get(startPoint.x + maxWidth, startPoint.y + yOffSett) ||
                visitedPoints.contains(new Point(startPoint.x + maxWidth, startPoint.y + yOffSett))) {
              searchFinished = true;
              break;
            }
          }
        }
        if(maxHeight >= maxWidth){
          for(int yOffSet = maxSquareLength; yOffSet < maxHeight; yOffSet++){
            for (int xOffSett = 0; xOffSett < maxSquareLength; xOffSett++) {
              visitedPoints.add(new Point(startPoint.x + xOffSett, startPoint.y + yOffSet));
            }
          }
          return new Point(maxSquareLength, maxHeight);
        } else {
          for(int xOffSett = maxSquareLength; xOffSett < maxWidth; xOffSett++){
            for (int yOffSet = 0; yOffSet < maxSquareLength; yOffSet++) {
              visitedPoints.add(new Point(startPoint.x + xOffSett, startPoint.y + yOffSet));
            }
          }
          return new Point(maxWidth, maxSquareLength);
        }
      }
    }
    
    24.04.2021
  • Արժանի որոշակի ճանաչման: Հրաշալի լուծում. Որոշ աննշան խնդիրներ փոփոխականի անվանման հետ կապված, բայց ո՞ւմ է հետաքրքրում, երբ դուք ստանում եք QR կոդ svg... Շնորհակալություն: 28.06.2021
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..